x86/mm/pat: Don't report PAT on CPUs that don't support it
[linux/fpc-iii.git] / drivers / media / platform / sti / c8sectpfe / c8sectpfe-dvb.c
blob2c0015b1264d3254451a7c56f9c9b1a69b760ad9
1 /*
2 * c8sectpfe-dvb.c - C8SECTPFE STi DVB driver
4 * Copyright (c) STMicroelectronics 2015
6 * Author Peter Griffin <peter.griffin@linaro.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 #include <linux/completion.h>
20 #include <linux/delay.h>
21 #include <linux/i2c.h>
22 #include <linux/interrupt.h>
23 #include <linux/version.h>
25 #include <dt-bindings/media/c8sectpfe.h>
27 #include "c8sectpfe-common.h"
28 #include "c8sectpfe-core.h"
29 #include "c8sectpfe-dvb.h"
31 #include "dvb-pll.h"
32 #include "lnbh24.h"
33 #include "stv0367.h"
34 #include "stv0367_priv.h"
35 #include "stv6110x.h"
36 #include "stv090x.h"
37 #include "tda18212.h"
39 static inline const char *dvb_card_str(unsigned int c)
41 switch (c) {
42 case STV0367_TDA18212_NIMA_1: return "STV0367_TDA18212_NIMA_1";
43 case STV0367_TDA18212_NIMA_2: return "STV0367_TDA18212_NIMA_2";
44 case STV0367_TDA18212_NIMB_1: return "STV0367_TDA18212_NIMB_1";
45 case STV0367_TDA18212_NIMB_2: return "STV0367_TDA18212_NIMB_2";
46 case STV0903_6110_LNB24_NIMA: return "STV0903_6110_LNB24_NIMA";
47 case STV0903_6110_LNB24_NIMB: return "STV0903_6110_LNB24_NIMB";
48 default: return "unknown dvb frontend card";
52 static struct stv090x_config stv090x_config = {
53 .device = STV0903,
54 .demod_mode = STV090x_SINGLE,
55 .clk_mode = STV090x_CLK_EXT,
56 .xtal = 16000000,
57 .address = 0x69,
59 .ts1_mode = STV090x_TSMODE_SERIAL_CONTINUOUS,
60 .ts2_mode = STV090x_TSMODE_SERIAL_CONTINUOUS,
62 .repeater_level = STV090x_RPTLEVEL_64,
64 .tuner_init = NULL,
65 .tuner_set_mode = NULL,
66 .tuner_set_frequency = NULL,
67 .tuner_get_frequency = NULL,
68 .tuner_set_bandwidth = NULL,
69 .tuner_get_bandwidth = NULL,
70 .tuner_set_bbgain = NULL,
71 .tuner_get_bbgain = NULL,
72 .tuner_set_refclk = NULL,
73 .tuner_get_status = NULL,
76 static struct stv6110x_config stv6110x_config = {
77 .addr = 0x60,
78 .refclk = 16000000,
81 #define NIMA 0
82 #define NIMB 1
84 static struct stv0367_config stv0367_tda18212_config[] = {
86 .demod_address = 0x1c,
87 .xtal = 16000000,
88 .if_khz = 4500,
89 .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
90 .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
91 .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
92 }, {
93 .demod_address = 0x1d,
94 .xtal = 16000000,
95 .if_khz = 4500,
96 .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
97 .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
98 .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
99 }, {
100 .demod_address = 0x1e,
101 .xtal = 16000000,
102 .if_khz = 4500,
103 .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
104 .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
105 .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
109 static struct tda18212_config tda18212_conf = {
110 .if_dvbt_6 = 4150,
111 .if_dvbt_7 = 4150,
112 .if_dvbt_8 = 4500,
113 .if_dvbc = 5000,
116 int c8sectpfe_frontend_attach(struct dvb_frontend **fe,
117 struct c8sectpfe *c8sectpfe,
118 struct channel_info *tsin, int chan_num)
120 struct tda18212_config *tda18212;
121 const struct stv6110x_devctl *fe2;
122 struct i2c_client *client;
123 struct i2c_board_info tda18212_info = {
124 .type = "tda18212",
125 .addr = 0x60,
128 if (!tsin)
129 return -EINVAL;
131 switch (tsin->dvb_card) {
133 case STV0367_TDA18212_NIMA_1:
134 case STV0367_TDA18212_NIMA_2:
135 case STV0367_TDA18212_NIMB_1:
136 case STV0367_TDA18212_NIMB_2:
137 if (tsin->dvb_card == STV0367_TDA18212_NIMA_1)
138 *fe = dvb_attach(stv0367ter_attach,
139 &stv0367_tda18212_config[0],
140 tsin->i2c_adapter);
141 else if (tsin->dvb_card == STV0367_TDA18212_NIMB_1)
142 *fe = dvb_attach(stv0367ter_attach,
143 &stv0367_tda18212_config[1],
144 tsin->i2c_adapter);
145 else
146 *fe = dvb_attach(stv0367ter_attach,
147 &stv0367_tda18212_config[2],
148 tsin->i2c_adapter);
150 if (!*fe) {
151 dev_err(c8sectpfe->device,
152 "%s: stv0367ter_attach failed for NIM card %s\n"
153 , __func__, dvb_card_str(tsin->dvb_card));
154 return -ENODEV;
158 * init the demod so that i2c gate_ctrl
159 * to the tuner works correctly
161 (*fe)->ops.init(*fe);
163 /* Allocate the tda18212 structure */
164 tda18212 = devm_kzalloc(c8sectpfe->device,
165 sizeof(struct tda18212_config),
166 GFP_KERNEL);
167 if (!tda18212) {
168 dev_err(c8sectpfe->device,
169 "%s: devm_kzalloc failed\n", __func__);
170 return -ENOMEM;
173 memcpy(tda18212, &tda18212_conf,
174 sizeof(struct tda18212_config));
176 tda18212->fe = (*fe);
178 tda18212_info.platform_data = tda18212;
180 /* attach tuner */
181 request_module("tda18212");
182 client = i2c_new_device(tsin->i2c_adapter, &tda18212_info);
183 if (!client || !client->dev.driver) {
184 dvb_frontend_detach(*fe);
185 return -ENODEV;
188 if (!try_module_get(client->dev.driver->owner)) {
189 i2c_unregister_device(client);
190 dvb_frontend_detach(*fe);
191 return -ENODEV;
194 tsin->i2c_client = client;
196 break;
198 case STV0903_6110_LNB24_NIMA:
199 *fe = dvb_attach(stv090x_attach, &stv090x_config,
200 tsin->i2c_adapter, STV090x_DEMODULATOR_0);
201 if (!*fe) {
202 dev_err(c8sectpfe->device, "%s: stv090x_attach failed\n"
203 "\tfor NIM card %s\n",
204 __func__, dvb_card_str(tsin->dvb_card));
205 return -ENODEV;
208 fe2 = dvb_attach(stv6110x_attach, *fe,
209 &stv6110x_config, tsin->i2c_adapter);
210 if (!fe2) {
211 dev_err(c8sectpfe->device,
212 "%s: stv6110x_attach failed for NIM card %s\n"
213 , __func__, dvb_card_str(tsin->dvb_card));
214 return -ENODEV;
217 stv090x_config.tuner_init = fe2->tuner_init;
218 stv090x_config.tuner_set_mode = fe2->tuner_set_mode;
219 stv090x_config.tuner_set_frequency = fe2->tuner_set_frequency;
220 stv090x_config.tuner_get_frequency = fe2->tuner_get_frequency;
221 stv090x_config.tuner_set_bandwidth = fe2->tuner_set_bandwidth;
222 stv090x_config.tuner_get_bandwidth = fe2->tuner_get_bandwidth;
223 stv090x_config.tuner_set_bbgain = fe2->tuner_set_bbgain;
224 stv090x_config.tuner_get_bbgain = fe2->tuner_get_bbgain;
225 stv090x_config.tuner_set_refclk = fe2->tuner_set_refclk;
226 stv090x_config.tuner_get_status = fe2->tuner_get_status;
228 dvb_attach(lnbh24_attach, *fe, tsin->i2c_adapter, 0, 0, 0x9);
229 break;
231 default:
232 dev_err(c8sectpfe->device,
233 "%s: DVB frontend card %s not yet supported\n",
234 __func__, dvb_card_str(tsin->dvb_card));
235 return -ENODEV;
238 (*fe)->id = chan_num;
240 dev_info(c8sectpfe->device,
241 "DVB frontend card %s successfully attached",
242 dvb_card_str(tsin->dvb_card));
243 return 0;