root/drivers/media/platform/sti/c8sectpfe/c8sectpfe-dvb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dvb_card_str
  2. c8sectpfe_frontend_attach

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  c8sectpfe-dvb.c - C8SECTPFE STi DVB driver
   4  *
   5  * Copyright (c) STMicroelectronics 2015
   6  *
   7  *  Author Peter Griffin <peter.griffin@linaro.org>
   8  *
   9  */
  10 #include <linux/completion.h>
  11 #include <linux/delay.h>
  12 #include <linux/i2c.h>
  13 #include <linux/interrupt.h>
  14 #include <linux/version.h>
  15 
  16 #include <dt-bindings/media/c8sectpfe.h>
  17 
  18 #include "c8sectpfe-common.h"
  19 #include "c8sectpfe-core.h"
  20 #include "c8sectpfe-dvb.h"
  21 
  22 #include "dvb-pll.h"
  23 #include "lnbh24.h"
  24 #include "stv0367.h"
  25 #include "stv0367_priv.h"
  26 #include "stv6110x.h"
  27 #include "stv090x.h"
  28 #include "tda18212.h"
  29 
  30 static inline const char *dvb_card_str(unsigned int c)
  31 {
  32         switch (c) {
  33         case STV0367_TDA18212_NIMA_1:   return "STV0367_TDA18212_NIMA_1";
  34         case STV0367_TDA18212_NIMA_2:   return "STV0367_TDA18212_NIMA_2";
  35         case STV0367_TDA18212_NIMB_1:   return "STV0367_TDA18212_NIMB_1";
  36         case STV0367_TDA18212_NIMB_2:   return "STV0367_TDA18212_NIMB_2";
  37         case STV0903_6110_LNB24_NIMA:   return "STV0903_6110_LNB24_NIMA";
  38         case STV0903_6110_LNB24_NIMB:   return "STV0903_6110_LNB24_NIMB";
  39         default:                        return "unknown dvb frontend card";
  40         }
  41 }
  42 
  43 static struct stv090x_config stv090x_config = {
  44         .device                 = STV0903,
  45         .demod_mode             = STV090x_SINGLE,
  46         .clk_mode               = STV090x_CLK_EXT,
  47         .xtal                   = 16000000,
  48         .address                = 0x69,
  49 
  50         .ts1_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
  51         .ts2_mode               = STV090x_TSMODE_SERIAL_CONTINUOUS,
  52 
  53         .repeater_level         = STV090x_RPTLEVEL_64,
  54 
  55         .tuner_init             = NULL,
  56         .tuner_set_mode         = NULL,
  57         .tuner_set_frequency    = NULL,
  58         .tuner_get_frequency    = NULL,
  59         .tuner_set_bandwidth    = NULL,
  60         .tuner_get_bandwidth    = NULL,
  61         .tuner_set_bbgain       = NULL,
  62         .tuner_get_bbgain       = NULL,
  63         .tuner_set_refclk       = NULL,
  64         .tuner_get_status       = NULL,
  65 };
  66 
  67 static struct stv6110x_config stv6110x_config = {
  68         .addr                   = 0x60,
  69         .refclk                 = 16000000,
  70 };
  71 
  72 #define NIMA 0
  73 #define NIMB 1
  74 
  75 static struct stv0367_config stv0367_tda18212_config[] = {
  76         {
  77                 .demod_address = 0x1c,
  78                 .xtal = 16000000,
  79                 .if_khz = 4500,
  80                 .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
  81                 .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
  82                 .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
  83         }, {
  84                 .demod_address = 0x1d,
  85                 .xtal = 16000000,
  86                 .if_khz = 4500,
  87                 .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
  88                 .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
  89                 .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
  90         }, {
  91                 .demod_address = 0x1e,
  92                 .xtal = 16000000,
  93                 .if_khz = 4500,
  94                 .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
  95                 .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
  96                 .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
  97         },
  98 };
  99 
 100 static struct tda18212_config tda18212_conf = {
 101         .if_dvbt_6 = 4150,
 102         .if_dvbt_7 = 4150,
 103         .if_dvbt_8 = 4500,
 104         .if_dvbc = 5000,
 105 };
 106 
 107 int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
 108                 struct c8sectpfe *c8sectpfe,
 109                 struct channel_info *tsin, int chan_num)
 110 {
 111         struct tda18212_config *tda18212;
 112         const struct stv6110x_devctl *fe2;
 113         struct i2c_client *client;
 114         struct i2c_board_info tda18212_info = {
 115                 .type = "tda18212",
 116                 .addr = 0x60,
 117         };
 118 
 119         if (!tsin)
 120                 return -EINVAL;
 121 
 122         switch (tsin->dvb_card) {
 123 
 124         case STV0367_TDA18212_NIMA_1:
 125         case STV0367_TDA18212_NIMA_2:
 126         case STV0367_TDA18212_NIMB_1:
 127         case STV0367_TDA18212_NIMB_2:
 128                 if (tsin->dvb_card == STV0367_TDA18212_NIMA_1)
 129                         *fe = dvb_attach(stv0367ter_attach,
 130                                  &stv0367_tda18212_config[0],
 131                                         tsin->i2c_adapter);
 132                 else if (tsin->dvb_card == STV0367_TDA18212_NIMB_1)
 133                         *fe = dvb_attach(stv0367ter_attach,
 134                                  &stv0367_tda18212_config[1],
 135                                         tsin->i2c_adapter);
 136                 else
 137                         *fe = dvb_attach(stv0367ter_attach,
 138                                  &stv0367_tda18212_config[2],
 139                                         tsin->i2c_adapter);
 140 
 141                 if (!*fe) {
 142                         dev_err(c8sectpfe->device,
 143                                 "%s: stv0367ter_attach failed for NIM card %s\n"
 144                                 , __func__, dvb_card_str(tsin->dvb_card));
 145                         return -ENODEV;
 146                 }
 147 
 148                 /*
 149                  * init the demod so that i2c gate_ctrl
 150                  * to the tuner works correctly
 151                  */
 152                 (*fe)->ops.init(*fe);
 153 
 154                 /* Allocate the tda18212 structure */
 155                 tda18212 = devm_kzalloc(c8sectpfe->device,
 156                                         sizeof(struct tda18212_config),
 157                                         GFP_KERNEL);
 158                 if (!tda18212) {
 159                         dev_err(c8sectpfe->device,
 160                                 "%s: devm_kzalloc failed\n", __func__);
 161                         return -ENOMEM;
 162                 }
 163 
 164                 memcpy(tda18212, &tda18212_conf,
 165                         sizeof(struct tda18212_config));
 166 
 167                 tda18212->fe = (*fe);
 168 
 169                 tda18212_info.platform_data = tda18212;
 170 
 171                 /* attach tuner */
 172                 request_module("tda18212");
 173                 client = i2c_new_device(tsin->i2c_adapter, &tda18212_info);
 174                 if (!client || !client->dev.driver) {
 175                         dvb_frontend_detach(*fe);
 176                         return -ENODEV;
 177                 }
 178 
 179                 if (!try_module_get(client->dev.driver->owner)) {
 180                         i2c_unregister_device(client);
 181                         dvb_frontend_detach(*fe);
 182                         return -ENODEV;
 183                 }
 184 
 185                 tsin->i2c_client = client;
 186 
 187                 break;
 188 
 189         case STV0903_6110_LNB24_NIMA:
 190                 *fe = dvb_attach(stv090x_attach,        &stv090x_config,
 191                                 tsin->i2c_adapter, STV090x_DEMODULATOR_0);
 192                 if (!*fe) {
 193                         dev_err(c8sectpfe->device, "%s: stv090x_attach failed\n"
 194                                 "\tfor NIM card %s\n",
 195                                 __func__, dvb_card_str(tsin->dvb_card));
 196                         return -ENODEV;
 197                 }
 198 
 199                 fe2 = dvb_attach(stv6110x_attach, *fe,
 200                                         &stv6110x_config, tsin->i2c_adapter);
 201                 if (!fe2) {
 202                         dev_err(c8sectpfe->device,
 203                                 "%s: stv6110x_attach failed for NIM card %s\n"
 204                                 , __func__, dvb_card_str(tsin->dvb_card));
 205                         return -ENODEV;
 206                 }
 207 
 208                 stv090x_config.tuner_init = fe2->tuner_init;
 209                 stv090x_config.tuner_set_mode = fe2->tuner_set_mode;
 210                 stv090x_config.tuner_set_frequency = fe2->tuner_set_frequency;
 211                 stv090x_config.tuner_get_frequency = fe2->tuner_get_frequency;
 212                 stv090x_config.tuner_set_bandwidth = fe2->tuner_set_bandwidth;
 213                 stv090x_config.tuner_get_bandwidth = fe2->tuner_get_bandwidth;
 214                 stv090x_config.tuner_set_bbgain = fe2->tuner_set_bbgain;
 215                 stv090x_config.tuner_get_bbgain = fe2->tuner_get_bbgain;
 216                 stv090x_config.tuner_set_refclk = fe2->tuner_set_refclk;
 217                 stv090x_config.tuner_get_status = fe2->tuner_get_status;
 218 
 219                 dvb_attach(lnbh24_attach, *fe, tsin->i2c_adapter, 0, 0, 0x9);
 220                 break;
 221 
 222         default:
 223                 dev_err(c8sectpfe->device,
 224                         "%s: DVB frontend card %s not yet supported\n",
 225                         __func__, dvb_card_str(tsin->dvb_card));
 226                 return -ENODEV;
 227         }
 228 
 229         (*fe)->id = chan_num;
 230 
 231         dev_info(c8sectpfe->device,
 232                         "DVB frontend card %s successfully attached",
 233                         dvb_card_str(tsin->dvb_card));
 234         return 0;
 235 }

/* [<][>][^][v][top][bottom][index][help] */