diff options
Diffstat (limited to 'drivers/media/dvb-frontends')
31 files changed, 1095 insertions, 1000 deletions
diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig index c645aa81f423..012225587c25 100644 --- a/drivers/media/dvb-frontends/Kconfig +++ b/drivers/media/dvb-frontends/Kconfig | |||
@@ -67,6 +67,7 @@ config DVB_TDA18271C2DD | |||
67 | config DVB_SI2165 | 67 | config DVB_SI2165 |
68 | tristate "Silicon Labs si2165 based" | 68 | tristate "Silicon Labs si2165 based" |
69 | depends on DVB_CORE && I2C | 69 | depends on DVB_CORE && I2C |
70 | select REGMAP_I2C | ||
70 | default m if !MEDIA_SUBDRV_AUTOSELECT | 71 | default m if !MEDIA_SUBDRV_AUTOSELECT |
71 | help | 72 | help |
72 | A DVB-C/T demodulator. | 73 | A DVB-C/T demodulator. |
@@ -463,6 +464,7 @@ config DVB_STV0367 | |||
463 | config DVB_CXD2820R | 464 | config DVB_CXD2820R |
464 | tristate "Sony CXD2820R" | 465 | tristate "Sony CXD2820R" |
465 | depends on DVB_CORE && I2C | 466 | depends on DVB_CORE && I2C |
467 | select REGMAP_I2C | ||
466 | default m if !MEDIA_SUBDRV_AUTOSELECT | 468 | default m if !MEDIA_SUBDRV_AUTOSELECT |
467 | help | 469 | help |
468 | Say Y when you want to support this frontend. | 470 | Say Y when you want to support this frontend. |
diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c index 8cc8c4597b6a..ad304eed656d 100644 --- a/drivers/media/dvb-frontends/ascot2e.c +++ b/drivers/media/dvb-frontends/ascot2e.c | |||
@@ -464,7 +464,7 @@ static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
464 | return 0; | 464 | return 0; |
465 | } | 465 | } |
466 | 466 | ||
467 | static struct dvb_tuner_ops ascot2e_tuner_ops = { | 467 | static const struct dvb_tuner_ops ascot2e_tuner_ops = { |
468 | .info = { | 468 | .info = { |
469 | .name = "Sony ASCOT2E", | 469 | .name = "Sony ASCOT2E", |
470 | .frequency_min = 1000000, | 470 | .frequency_min = 1000000, |
diff --git a/drivers/media/dvb-frontends/cxd2820r.h b/drivers/media/dvb-frontends/cxd2820r.h index 297a71a671f5..f3ff8f6eb3bb 100644 --- a/drivers/media/dvb-frontends/cxd2820r.h +++ b/drivers/media/dvb-frontends/cxd2820r.h | |||
@@ -36,6 +36,32 @@ | |||
36 | #define CXD2820R_TS_PARALLEL 0x30 | 36 | #define CXD2820R_TS_PARALLEL 0x30 |
37 | #define CXD2820R_TS_PARALLEL_MSB 0x70 | 37 | #define CXD2820R_TS_PARALLEL_MSB 0x70 |
38 | 38 | ||
39 | /* | ||
40 | * I2C address: 0x6c, 0x6d | ||
41 | */ | ||
42 | |||
43 | /** | ||
44 | * struct cxd2820r_platform_data - Platform data for the cxd2820r driver | ||
45 | * @ts_mode: TS mode. | ||
46 | * @ts_clk_inv: TS clock inverted. | ||
47 | * @if_agc_polarity: IF AGC polarity. | ||
48 | * @spec_inv: Input spectrum inverted. | ||
49 | * @gpio_chip_base: GPIO. | ||
50 | * @get_dvb_frontend: Get DVB frontend. | ||
51 | */ | ||
52 | |||
53 | struct cxd2820r_platform_data { | ||
54 | u8 ts_mode; | ||
55 | bool ts_clk_inv; | ||
56 | bool if_agc_polarity; | ||
57 | bool spec_inv; | ||
58 | int **gpio_chip_base; | ||
59 | |||
60 | struct dvb_frontend* (*get_dvb_frontend)(struct i2c_client *); | ||
61 | /* private: For legacy media attach wrapper. Do not set value. */ | ||
62 | bool attach_in_use; | ||
63 | }; | ||
64 | |||
39 | struct cxd2820r_config { | 65 | struct cxd2820r_config { |
40 | /* Demodulator I2C address. | 66 | /* Demodulator I2C address. |
41 | * Driver determines DVB-C slave I2C address automatically from master | 67 | * Driver determines DVB-C slave I2C address automatically from master |
diff --git a/drivers/media/dvb-frontends/cxd2820r_c.c b/drivers/media/dvb-frontends/cxd2820r_c.c index a674a6312c38..d75b0776d5b5 100644 --- a/drivers/media/dvb-frontends/cxd2820r_c.c +++ b/drivers/media/dvb-frontends/cxd2820r_c.c | |||
@@ -24,12 +24,12 @@ | |||
24 | int cxd2820r_set_frontend_c(struct dvb_frontend *fe) | 24 | int cxd2820r_set_frontend_c(struct dvb_frontend *fe) |
25 | { | 25 | { |
26 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 26 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
27 | struct i2c_client *client = priv->client[0]; | ||
27 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
28 | int ret, i; | 29 | int ret; |
30 | unsigned int utmp; | ||
29 | u8 buf[2]; | 31 | u8 buf[2]; |
30 | u32 if_freq; | 32 | u32 if_frequency; |
31 | u16 if_ctl; | ||
32 | u64 num; | ||
33 | struct reg_val_mask tab[] = { | 33 | struct reg_val_mask tab[] = { |
34 | { 0x00080, 0x01, 0xff }, | 34 | { 0x00080, 0x01, 0xff }, |
35 | { 0x00081, 0x05, 0xff }, | 35 | { 0x00081, 0x05, 0xff }, |
@@ -43,25 +43,24 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) | |||
43 | { 0x10059, 0x50, 0xff }, | 43 | { 0x10059, 0x50, 0xff }, |
44 | { 0x10087, 0x0c, 0x3c }, | 44 | { 0x10087, 0x0c, 0x3c }, |
45 | { 0x1008b, 0x07, 0xff }, | 45 | { 0x1008b, 0x07, 0xff }, |
46 | { 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 }, | 46 | { 0x1001f, priv->if_agc_polarity << 7, 0x80 }, |
47 | { 0x10070, priv->cfg.ts_mode, 0xff }, | 47 | { 0x10070, priv->ts_mode, 0xff }, |
48 | { 0x10071, !priv->cfg.ts_clock_inv << 4, 0x10 }, | 48 | { 0x10071, !priv->ts_clk_inv << 4, 0x10 }, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | dev_dbg(&priv->i2c->dev, "%s: frequency=%d symbol_rate=%d\n", __func__, | 51 | dev_dbg(&client->dev, |
52 | c->frequency, c->symbol_rate); | 52 | "delivery_system=%d modulation=%d frequency=%u symbol_rate=%u inversion=%d\n", |
53 | c->delivery_system, c->modulation, c->frequency, | ||
54 | c->symbol_rate, c->inversion); | ||
53 | 55 | ||
54 | /* program tuner */ | 56 | /* program tuner */ |
55 | if (fe->ops.tuner_ops.set_params) | 57 | if (fe->ops.tuner_ops.set_params) |
56 | fe->ops.tuner_ops.set_params(fe); | 58 | fe->ops.tuner_ops.set_params(fe); |
57 | 59 | ||
58 | if (priv->delivery_system != SYS_DVBC_ANNEX_A) { | 60 | if (priv->delivery_system != SYS_DVBC_ANNEX_A) { |
59 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | 61 | ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); |
60 | ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, | 62 | if (ret) |
61 | tab[i].val, tab[i].mask); | 63 | goto error; |
62 | if (ret) | ||
63 | goto error; | ||
64 | } | ||
65 | } | 64 | } |
66 | 65 | ||
67 | priv->delivery_system = SYS_DVBC_ANNEX_A; | 66 | priv->delivery_system = SYS_DVBC_ANNEX_A; |
@@ -69,35 +68,33 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe) | |||
69 | 68 | ||
70 | /* program IF frequency */ | 69 | /* program IF frequency */ |
71 | if (fe->ops.tuner_ops.get_if_frequency) { | 70 | if (fe->ops.tuner_ops.get_if_frequency) { |
72 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); | 71 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); |
73 | if (ret) | 72 | if (ret) |
74 | goto error; | 73 | goto error; |
75 | } else | 74 | dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency); |
76 | if_freq = 0; | 75 | } else { |
77 | 76 | ret = -EINVAL; | |
78 | dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq); | 77 | goto error; |
79 | 78 | } | |
80 | num = if_freq / 1000; /* Hz => kHz */ | ||
81 | num *= 0x4000; | ||
82 | if_ctl = 0x4000 - DIV_ROUND_CLOSEST_ULL(num, 41000); | ||
83 | buf[0] = (if_ctl >> 8) & 0x3f; | ||
84 | buf[1] = (if_ctl >> 0) & 0xff; | ||
85 | 79 | ||
86 | ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2); | 80 | utmp = 0x4000 - DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x4000, CXD2820R_CLK); |
81 | buf[0] = (utmp >> 8) & 0xff; | ||
82 | buf[1] = (utmp >> 0) & 0xff; | ||
83 | ret = regmap_bulk_write(priv->regmap[1], 0x0042, buf, 2); | ||
87 | if (ret) | 84 | if (ret) |
88 | goto error; | 85 | goto error; |
89 | 86 | ||
90 | ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08); | 87 | ret = regmap_write(priv->regmap[0], 0x00ff, 0x08); |
91 | if (ret) | 88 | if (ret) |
92 | goto error; | 89 | goto error; |
93 | 90 | ||
94 | ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01); | 91 | ret = regmap_write(priv->regmap[0], 0x00fe, 0x01); |
95 | if (ret) | 92 | if (ret) |
96 | goto error; | 93 | goto error; |
97 | 94 | ||
98 | return ret; | 95 | return ret; |
99 | error: | 96 | error: |
100 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 97 | dev_dbg(&client->dev, "failed=%d\n", ret); |
101 | return ret; | 98 | return ret; |
102 | } | 99 | } |
103 | 100 | ||
@@ -105,20 +102,24 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe, | |||
105 | struct dtv_frontend_properties *c) | 102 | struct dtv_frontend_properties *c) |
106 | { | 103 | { |
107 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 104 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
105 | struct i2c_client *client = priv->client[0]; | ||
108 | int ret; | 106 | int ret; |
107 | unsigned int utmp; | ||
109 | u8 buf[2]; | 108 | u8 buf[2]; |
110 | 109 | ||
111 | ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2); | 110 | dev_dbg(&client->dev, "\n"); |
111 | |||
112 | ret = regmap_bulk_read(priv->regmap[1], 0x001a, buf, 2); | ||
112 | if (ret) | 113 | if (ret) |
113 | goto error; | 114 | goto error; |
114 | 115 | ||
115 | c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]); | 116 | c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]); |
116 | 117 | ||
117 | ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]); | 118 | ret = regmap_read(priv->regmap[1], 0x0019, &utmp); |
118 | if (ret) | 119 | if (ret) |
119 | goto error; | 120 | goto error; |
120 | 121 | ||
121 | switch ((buf[0] >> 0) & 0x07) { | 122 | switch ((utmp >> 0) & 0x07) { |
122 | case 0: | 123 | case 0: |
123 | c->modulation = QAM_16; | 124 | c->modulation = QAM_16; |
124 | break; | 125 | break; |
@@ -136,7 +137,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe, | |||
136 | break; | 137 | break; |
137 | } | 138 | } |
138 | 139 | ||
139 | switch ((buf[0] >> 7) & 0x01) { | 140 | switch ((utmp >> 7) & 0x01) { |
140 | case 0: | 141 | case 0: |
141 | c->inversion = INVERSION_OFF; | 142 | c->inversion = INVERSION_OFF; |
142 | break; | 143 | break; |
@@ -147,167 +148,169 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe, | |||
147 | 148 | ||
148 | return ret; | 149 | return ret; |
149 | error: | 150 | error: |
150 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 151 | dev_dbg(&client->dev, "failed=%d\n", ret); |
151 | return ret; | 152 | return ret; |
152 | } | 153 | } |
153 | 154 | ||
154 | int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber) | 155 | int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status) |
155 | { | 156 | { |
156 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 157 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
158 | struct i2c_client *client = priv->client[0]; | ||
159 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
157 | int ret; | 160 | int ret; |
158 | u8 buf[3], start_ber = 0; | 161 | unsigned int utmp, utmp1, utmp2; |
159 | *ber = 0; | 162 | u8 buf[3]; |
160 | 163 | ||
161 | if (priv->ber_running) { | 164 | /* Lock detection */ |
162 | ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf)); | 165 | ret = regmap_bulk_read(priv->regmap[1], 0x0088, &buf[0], 1); |
163 | if (ret) | 166 | if (ret) |
164 | goto error; | 167 | goto error; |
168 | ret = regmap_bulk_read(priv->regmap[1], 0x0073, &buf[1], 1); | ||
169 | if (ret) | ||
170 | goto error; | ||
165 | 171 | ||
166 | if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) { | 172 | utmp1 = (buf[0] >> 0) & 0x01; |
167 | *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0]; | 173 | utmp2 = (buf[1] >> 3) & 0x01; |
168 | start_ber = 1; | 174 | |
169 | } | 175 | if (utmp1 == 1 && utmp2 == 1) { |
176 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
177 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
178 | } else if (utmp1 == 1 || utmp2 == 1) { | ||
179 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
180 | FE_HAS_VITERBI | FE_HAS_SYNC; | ||
170 | } else { | 181 | } else { |
171 | priv->ber_running = true; | 182 | *status = 0; |
172 | start_ber = 1; | ||
173 | } | 183 | } |
174 | 184 | ||
175 | if (start_ber) { | 185 | dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n", |
176 | /* (re)start BER */ | 186 | *status, 2, buf, utmp1, utmp2); |
177 | ret = cxd2820r_wr_reg(priv, 0x10079, 0x01); | ||
178 | if (ret) | ||
179 | goto error; | ||
180 | } | ||
181 | 187 | ||
182 | return ret; | 188 | /* Signal strength */ |
183 | error: | 189 | if (*status & FE_HAS_SIGNAL) { |
184 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 190 | unsigned int strength; |
185 | return ret; | ||
186 | } | ||
187 | 191 | ||
188 | int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, | 192 | ret = regmap_bulk_read(priv->regmap[1], 0x0049, buf, 2); |
189 | u16 *strength) | 193 | if (ret) |
190 | { | 194 | goto error; |
191 | struct cxd2820r_priv *priv = fe->demodulator_priv; | ||
192 | int ret; | ||
193 | u8 buf[2]; | ||
194 | u16 tmp; | ||
195 | 195 | ||
196 | ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf)); | 196 | utmp = buf[0] << 8 | buf[1] << 0; |
197 | if (ret) | 197 | utmp = 511 - sign_extend32(utmp, 9); |
198 | goto error; | 198 | /* Scale value to 0x0000-0xffff */ |
199 | strength = utmp << 6 | utmp >> 4; | ||
199 | 200 | ||
200 | tmp = (buf[0] & 0x03) << 8 | buf[1]; | 201 | c->strength.len = 1; |
201 | tmp = (~tmp & 0x03ff); | 202 | c->strength.stat[0].scale = FE_SCALE_RELATIVE; |
203 | c->strength.stat[0].uvalue = strength; | ||
204 | } else { | ||
205 | c->strength.len = 1; | ||
206 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
207 | } | ||
202 | 208 | ||
203 | if (tmp == 512) | 209 | /* CNR */ |
204 | /* ~no signal */ | 210 | if (*status & FE_HAS_VITERBI) { |
205 | tmp = 0; | 211 | unsigned int cnr, const_a, const_b; |
206 | else if (tmp > 350) | ||
207 | tmp = 350; | ||
208 | 212 | ||
209 | /* scale value to 0x0000-0xffff */ | 213 | ret = regmap_read(priv->regmap[1], 0x0019, &utmp); |
210 | *strength = tmp * 0xffff / (350-0); | 214 | if (ret) |
215 | goto error; | ||
211 | 216 | ||
212 | return ret; | 217 | if (((utmp >> 0) & 0x03) % 2) { |
213 | error: | 218 | const_a = 8750; |
214 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 219 | const_b = 650; |
215 | return ret; | 220 | } else { |
216 | } | 221 | const_a = 9500; |
222 | const_b = 760; | ||
223 | } | ||
217 | 224 | ||
218 | int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr) | 225 | ret = regmap_read(priv->regmap[1], 0x004d, &utmp); |
219 | { | 226 | if (ret) |
220 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 227 | goto error; |
221 | int ret; | ||
222 | u8 tmp; | ||
223 | unsigned int A, B; | ||
224 | /* report SNR in dB * 10 */ | ||
225 | 228 | ||
226 | ret = cxd2820r_rd_reg(priv, 0x10019, &tmp); | 229 | #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */ |
227 | if (ret) | 230 | if (utmp) |
228 | goto error; | 231 | cnr = div_u64((u64)(intlog2(const_b) - intlog2(utmp)) |
232 | * const_a, CXD2820R_LOG2_E_24); | ||
233 | else | ||
234 | cnr = 0; | ||
229 | 235 | ||
230 | if (((tmp >> 0) & 0x03) % 2) { | 236 | c->cnr.len = 1; |
231 | A = 875; | 237 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
232 | B = 650; | 238 | c->cnr.stat[0].svalue = cnr; |
233 | } else { | 239 | } else { |
234 | A = 950; | 240 | c->cnr.len = 1; |
235 | B = 760; | 241 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
236 | } | 242 | } |
237 | 243 | ||
238 | ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp); | 244 | /* BER */ |
239 | if (ret) | 245 | if (*status & FE_HAS_SYNC) { |
240 | goto error; | 246 | unsigned int post_bit_error; |
241 | 247 | bool start_ber; | |
242 | #define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */ | ||
243 | if (tmp) | ||
244 | *snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5) | ||
245 | / 10; | ||
246 | else | ||
247 | *snr = 0; | ||
248 | |||
249 | return ret; | ||
250 | error: | ||
251 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
252 | return ret; | ||
253 | } | ||
254 | 248 | ||
255 | int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks) | 249 | if (priv->ber_running) { |
256 | { | 250 | ret = regmap_bulk_read(priv->regmap[1], 0x0076, buf, 3); |
257 | *ucblocks = 0; | 251 | if (ret) |
258 | /* no way to read ? */ | 252 | goto error; |
259 | return 0; | ||
260 | } | ||
261 | 253 | ||
262 | int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status) | 254 | if ((buf[2] >> 7) & 0x01) { |
263 | { | 255 | post_bit_error = buf[2] << 16 | buf[1] << 8 | |
264 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 256 | buf[0] << 0; |
265 | int ret; | 257 | post_bit_error &= 0x0fffff; |
266 | u8 buf[2]; | 258 | start_ber = true; |
267 | *status = 0; | 259 | } else { |
260 | post_bit_error = 0; | ||
261 | start_ber = false; | ||
262 | } | ||
263 | } else { | ||
264 | post_bit_error = 0; | ||
265 | start_ber = true; | ||
266 | } | ||
268 | 267 | ||
269 | ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf)); | 268 | if (start_ber) { |
270 | if (ret) | 269 | ret = regmap_write(priv->regmap[1], 0x0079, 0x01); |
271 | goto error; | 270 | if (ret) |
271 | goto error; | ||
272 | priv->ber_running = true; | ||
273 | } | ||
272 | 274 | ||
273 | if (((buf[0] >> 0) & 0x01) == 1) { | 275 | priv->post_bit_error += post_bit_error; |
274 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
275 | FE_HAS_VITERBI | FE_HAS_SYNC; | ||
276 | 276 | ||
277 | if (((buf[1] >> 3) & 0x01) == 1) { | 277 | c->post_bit_error.len = 1; |
278 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | 278 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; |
279 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | 279 | c->post_bit_error.stat[0].uvalue = priv->post_bit_error; |
280 | } | 280 | } else { |
281 | c->post_bit_error.len = 1; | ||
282 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
281 | } | 283 | } |
282 | 284 | ||
283 | dev_dbg(&priv->i2c->dev, "%s: lock=%02x %02x\n", __func__, buf[0], | ||
284 | buf[1]); | ||
285 | |||
286 | return ret; | 285 | return ret; |
287 | error: | 286 | error: |
288 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 287 | dev_dbg(&client->dev, "failed=%d\n", ret); |
289 | return ret; | 288 | return ret; |
290 | } | 289 | } |
291 | 290 | ||
292 | int cxd2820r_init_c(struct dvb_frontend *fe) | 291 | int cxd2820r_init_c(struct dvb_frontend *fe) |
293 | { | 292 | { |
294 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 293 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
294 | struct i2c_client *client = priv->client[0]; | ||
295 | int ret; | 295 | int ret; |
296 | 296 | ||
297 | ret = cxd2820r_wr_reg(priv, 0x00085, 0x07); | 297 | dev_dbg(&client->dev, "\n"); |
298 | |||
299 | ret = regmap_write(priv->regmap[0], 0x0085, 0x07); | ||
298 | if (ret) | 300 | if (ret) |
299 | goto error; | 301 | goto error; |
300 | 302 | ||
301 | return ret; | 303 | return ret; |
302 | error: | 304 | error: |
303 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 305 | dev_dbg(&client->dev, "failed=%d\n", ret); |
304 | return ret; | 306 | return ret; |
305 | } | 307 | } |
306 | 308 | ||
307 | int cxd2820r_sleep_c(struct dvb_frontend *fe) | 309 | int cxd2820r_sleep_c(struct dvb_frontend *fe) |
308 | { | 310 | { |
309 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 311 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
310 | int ret, i; | 312 | struct i2c_client *client = priv->client[0]; |
313 | int ret; | ||
311 | struct reg_val_mask tab[] = { | 314 | struct reg_val_mask tab[] = { |
312 | { 0x000ff, 0x1f, 0xff }, | 315 | { 0x000ff, 0x1f, 0xff }, |
313 | { 0x00085, 0x00, 0xff }, | 316 | { 0x00085, 0x00, 0xff }, |
@@ -316,20 +319,17 @@ int cxd2820r_sleep_c(struct dvb_frontend *fe) | |||
316 | { 0x00080, 0x00, 0xff }, | 319 | { 0x00080, 0x00, 0xff }, |
317 | }; | 320 | }; |
318 | 321 | ||
319 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); | 322 | dev_dbg(&client->dev, "\n"); |
320 | 323 | ||
321 | priv->delivery_system = SYS_UNDEFINED; | 324 | priv->delivery_system = SYS_UNDEFINED; |
322 | 325 | ||
323 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | 326 | ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); |
324 | ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val, | 327 | if (ret) |
325 | tab[i].mask); | 328 | goto error; |
326 | if (ret) | ||
327 | goto error; | ||
328 | } | ||
329 | 329 | ||
330 | return ret; | 330 | return ret; |
331 | error: | 331 | error: |
332 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 332 | dev_dbg(&client->dev, "failed=%d\n", ret); |
333 | return ret; | 333 | return ret; |
334 | } | 334 | } |
335 | 335 | ||
diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 314d3b8c1080..95267c6edb3a 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c | |||
@@ -21,178 +21,50 @@ | |||
21 | 21 | ||
22 | #include "cxd2820r_priv.h" | 22 | #include "cxd2820r_priv.h" |
23 | 23 | ||
24 | /* Max transfer size done by I2C transfer functions */ | 24 | /* Write register table */ |
25 | #define MAX_XFER_SIZE 64 | 25 | int cxd2820r_wr_reg_val_mask_tab(struct cxd2820r_priv *priv, |
26 | 26 | const struct reg_val_mask *tab, int tab_len) | |
27 | /* write multiple registers */ | ||
28 | static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, | ||
29 | u8 *val, int len) | ||
30 | { | ||
31 | int ret; | ||
32 | u8 buf[MAX_XFER_SIZE]; | ||
33 | struct i2c_msg msg[1] = { | ||
34 | { | ||
35 | .addr = i2c, | ||
36 | .flags = 0, | ||
37 | .len = len + 1, | ||
38 | .buf = buf, | ||
39 | } | ||
40 | }; | ||
41 | |||
42 | if (1 + len > sizeof(buf)) { | ||
43 | dev_warn(&priv->i2c->dev, | ||
44 | "%s: i2c wr reg=%04x: len=%d is too big!\n", | ||
45 | KBUILD_MODNAME, reg, len); | ||
46 | return -EINVAL; | ||
47 | } | ||
48 | |||
49 | buf[0] = reg; | ||
50 | memcpy(&buf[1], val, len); | ||
51 | |||
52 | ret = i2c_transfer(priv->i2c, msg, 1); | ||
53 | if (ret == 1) { | ||
54 | ret = 0; | ||
55 | } else { | ||
56 | dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ | ||
57 | "len=%d\n", KBUILD_MODNAME, ret, reg, len); | ||
58 | ret = -EREMOTEIO; | ||
59 | } | ||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | /* read multiple registers */ | ||
64 | static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg, | ||
65 | u8 *val, int len) | ||
66 | { | ||
67 | int ret; | ||
68 | u8 buf[MAX_XFER_SIZE]; | ||
69 | struct i2c_msg msg[2] = { | ||
70 | { | ||
71 | .addr = i2c, | ||
72 | .flags = 0, | ||
73 | .len = 1, | ||
74 | .buf = ®, | ||
75 | }, { | ||
76 | .addr = i2c, | ||
77 | .flags = I2C_M_RD, | ||
78 | .len = len, | ||
79 | .buf = buf, | ||
80 | } | ||
81 | }; | ||
82 | |||
83 | if (len > sizeof(buf)) { | ||
84 | dev_warn(&priv->i2c->dev, | ||
85 | "%s: i2c wr reg=%04x: len=%d is too big!\n", | ||
86 | KBUILD_MODNAME, reg, len); | ||
87 | return -EINVAL; | ||
88 | } | ||
89 | |||
90 | ret = i2c_transfer(priv->i2c, msg, 2); | ||
91 | if (ret == 2) { | ||
92 | memcpy(val, buf, len); | ||
93 | ret = 0; | ||
94 | } else { | ||
95 | dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ | ||
96 | "len=%d\n", KBUILD_MODNAME, ret, reg, len); | ||
97 | ret = -EREMOTEIO; | ||
98 | } | ||
99 | |||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | /* write multiple registers */ | ||
104 | int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, | ||
105 | int len) | ||
106 | { | 27 | { |
28 | struct i2c_client *client = priv->client[0]; | ||
107 | int ret; | 29 | int ret; |
108 | u8 i2c_addr; | 30 | unsigned int i, reg, mask, val; |
109 | u8 reg = (reginfo >> 0) & 0xff; | 31 | struct regmap *regmap; |
110 | u8 bank = (reginfo >> 8) & 0xff; | ||
111 | u8 i2c = (reginfo >> 16) & 0x01; | ||
112 | |||
113 | /* select I2C */ | ||
114 | if (i2c) | ||
115 | i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */ | ||
116 | else | ||
117 | i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */ | ||
118 | 32 | ||
119 | /* switch bank if needed */ | 33 | dev_dbg(&client->dev, "tab_len=%d\n", tab_len); |
120 | if (bank != priv->bank[i2c]) { | ||
121 | ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1); | ||
122 | if (ret) | ||
123 | return ret; | ||
124 | priv->bank[i2c] = bank; | ||
125 | } | ||
126 | return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len); | ||
127 | } | ||
128 | |||
129 | /* read multiple registers */ | ||
130 | int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val, | ||
131 | int len) | ||
132 | { | ||
133 | int ret; | ||
134 | u8 i2c_addr; | ||
135 | u8 reg = (reginfo >> 0) & 0xff; | ||
136 | u8 bank = (reginfo >> 8) & 0xff; | ||
137 | u8 i2c = (reginfo >> 16) & 0x01; | ||
138 | |||
139 | /* select I2C */ | ||
140 | if (i2c) | ||
141 | i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */ | ||
142 | else | ||
143 | i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */ | ||
144 | 34 | ||
145 | /* switch bank if needed */ | 35 | for (i = 0; i < tab_len; i++) { |
146 | if (bank != priv->bank[i2c]) { | 36 | if ((tab[i].reg >> 16) & 0x1) |
147 | ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1); | 37 | regmap = priv->regmap[1]; |
148 | if (ret) | 38 | else |
149 | return ret; | 39 | regmap = priv->regmap[0]; |
150 | priv->bank[i2c] = bank; | ||
151 | } | ||
152 | return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len); | ||
153 | } | ||
154 | |||
155 | /* write single register */ | ||
156 | int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val) | ||
157 | { | ||
158 | return cxd2820r_wr_regs(priv, reg, &val, 1); | ||
159 | } | ||
160 | |||
161 | /* read single register */ | ||
162 | int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val) | ||
163 | { | ||
164 | return cxd2820r_rd_regs(priv, reg, val, 1); | ||
165 | } | ||
166 | 40 | ||
167 | /* write single register with mask */ | 41 | reg = (tab[i].reg >> 0) & 0xffff; |
168 | int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, | 42 | val = tab[i].val; |
169 | u8 mask) | 43 | mask = tab[i].mask; |
170 | { | ||
171 | int ret; | ||
172 | u8 tmp; | ||
173 | 44 | ||
174 | /* no need for read if whole reg is written */ | 45 | if (mask == 0xff) |
175 | if (mask != 0xff) { | 46 | ret = regmap_write(regmap, reg, val); |
176 | ret = cxd2820r_rd_reg(priv, reg, &tmp); | 47 | else |
48 | ret = regmap_write_bits(regmap, reg, mask, val); | ||
177 | if (ret) | 49 | if (ret) |
178 | return ret; | 50 | goto error; |
179 | |||
180 | val &= mask; | ||
181 | tmp &= ~mask; | ||
182 | val |= tmp; | ||
183 | } | 51 | } |
184 | 52 | ||
185 | return cxd2820r_wr_reg(priv, reg, val); | 53 | return 0; |
54 | error: | ||
55 | dev_dbg(&client->dev, "failed=%d\n", ret); | ||
56 | return ret; | ||
186 | } | 57 | } |
187 | 58 | ||
188 | int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) | 59 | int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) |
189 | { | 60 | { |
190 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 61 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
62 | struct i2c_client *client = priv->client[0]; | ||
63 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
191 | int ret, i; | 64 | int ret, i; |
192 | u8 tmp0, tmp1; | 65 | u8 tmp0, tmp1; |
193 | 66 | ||
194 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 67 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
195 | fe->dtv_property_cache.delivery_system); | ||
196 | 68 | ||
197 | /* update GPIOs only when needed */ | 69 | /* update GPIOs only when needed */ |
198 | if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio))) | 70 | if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio))) |
@@ -219,20 +91,18 @@ int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) | |||
219 | else | 91 | else |
220 | tmp1 |= (0 << (0 + i)); | 92 | tmp1 |= (0 << (0 + i)); |
221 | 93 | ||
222 | dev_dbg(&priv->i2c->dev, "%s: gpio i=%d %02x %02x\n", __func__, | 94 | dev_dbg(&client->dev, "gpio i=%d %02x %02x\n", i, tmp0, tmp1); |
223 | i, tmp0, tmp1); | ||
224 | } | 95 | } |
225 | 96 | ||
226 | dev_dbg(&priv->i2c->dev, "%s: wr gpio=%02x %02x\n", __func__, tmp0, | 97 | dev_dbg(&client->dev, "wr gpio=%02x %02x\n", tmp0, tmp1); |
227 | tmp1); | ||
228 | 98 | ||
229 | /* write bits [7:2] */ | 99 | /* write bits [7:2] */ |
230 | ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc); | 100 | ret = regmap_update_bits(priv->regmap[0], 0x0089, 0xfc, tmp0); |
231 | if (ret) | 101 | if (ret) |
232 | goto error; | 102 | goto error; |
233 | 103 | ||
234 | /* write bits [5:0] */ | 104 | /* write bits [5:0] */ |
235 | ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f); | 105 | ret = regmap_update_bits(priv->regmap[0], 0x008e, 0x3f, tmp1); |
236 | if (ret) | 106 | if (ret) |
237 | goto error; | 107 | goto error; |
238 | 108 | ||
@@ -240,18 +110,18 @@ int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio) | |||
240 | 110 | ||
241 | return ret; | 111 | return ret; |
242 | error: | 112 | error: |
243 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 113 | dev_dbg(&client->dev, "failed=%d\n", ret); |
244 | return ret; | 114 | return ret; |
245 | } | 115 | } |
246 | 116 | ||
247 | static int cxd2820r_set_frontend(struct dvb_frontend *fe) | 117 | static int cxd2820r_set_frontend(struct dvb_frontend *fe) |
248 | { | 118 | { |
249 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 119 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
120 | struct i2c_client *client = priv->client[0]; | ||
250 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 121 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
251 | int ret; | 122 | int ret; |
252 | 123 | ||
253 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 124 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
254 | fe->dtv_property_cache.delivery_system); | ||
255 | 125 | ||
256 | switch (c->delivery_system) { | 126 | switch (c->delivery_system) { |
257 | case SYS_DVBT: | 127 | case SYS_DVBT: |
@@ -279,8 +149,7 @@ static int cxd2820r_set_frontend(struct dvb_frontend *fe) | |||
279 | goto err; | 149 | goto err; |
280 | break; | 150 | break; |
281 | default: | 151 | default: |
282 | dev_dbg(&priv->i2c->dev, "%s: error state=%d\n", __func__, | 152 | dev_dbg(&client->dev, "invalid delivery_system\n"); |
283 | fe->dtv_property_cache.delivery_system); | ||
284 | ret = -EINVAL; | 153 | ret = -EINVAL; |
285 | break; | 154 | break; |
286 | } | 155 | } |
@@ -291,12 +160,13 @@ err: | |||
291 | static int cxd2820r_read_status(struct dvb_frontend *fe, enum fe_status *status) | 160 | static int cxd2820r_read_status(struct dvb_frontend *fe, enum fe_status *status) |
292 | { | 161 | { |
293 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 162 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
163 | struct i2c_client *client = priv->client[0]; | ||
164 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
294 | int ret; | 165 | int ret; |
295 | 166 | ||
296 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 167 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
297 | fe->dtv_property_cache.delivery_system); | ||
298 | 168 | ||
299 | switch (fe->dtv_property_cache.delivery_system) { | 169 | switch (c->delivery_system) { |
300 | case SYS_DVBT: | 170 | case SYS_DVBT: |
301 | ret = cxd2820r_read_status_t(fe, status); | 171 | ret = cxd2820r_read_status_t(fe, status); |
302 | break; | 172 | break; |
@@ -317,15 +187,16 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe, | |||
317 | struct dtv_frontend_properties *p) | 187 | struct dtv_frontend_properties *p) |
318 | { | 188 | { |
319 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 189 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
190 | struct i2c_client *client = priv->client[0]; | ||
191 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
320 | int ret; | 192 | int ret; |
321 | 193 | ||
322 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 194 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
323 | fe->dtv_property_cache.delivery_system); | ||
324 | 195 | ||
325 | if (priv->delivery_system == SYS_UNDEFINED) | 196 | if (priv->delivery_system == SYS_UNDEFINED) |
326 | return 0; | 197 | return 0; |
327 | 198 | ||
328 | switch (fe->dtv_property_cache.delivery_system) { | 199 | switch (c->delivery_system) { |
329 | case SYS_DVBT: | 200 | case SYS_DVBT: |
330 | ret = cxd2820r_get_frontend_t(fe, p); | 201 | ret = cxd2820r_get_frontend_t(fe, p); |
331 | break; | 202 | break; |
@@ -345,101 +216,60 @@ static int cxd2820r_get_frontend(struct dvb_frontend *fe, | |||
345 | static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber) | 216 | static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber) |
346 | { | 217 | { |
347 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 218 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
348 | int ret; | 219 | struct i2c_client *client = priv->client[0]; |
220 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
349 | 221 | ||
350 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 222 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
351 | fe->dtv_property_cache.delivery_system); | ||
352 | 223 | ||
353 | switch (fe->dtv_property_cache.delivery_system) { | 224 | *ber = (priv->post_bit_error - priv->post_bit_error_prev_dvbv3); |
354 | case SYS_DVBT: | 225 | priv->post_bit_error_prev_dvbv3 = priv->post_bit_error; |
355 | ret = cxd2820r_read_ber_t(fe, ber); | 226 | |
356 | break; | 227 | return 0; |
357 | case SYS_DVBT2: | ||
358 | ret = cxd2820r_read_ber_t2(fe, ber); | ||
359 | break; | ||
360 | case SYS_DVBC_ANNEX_A: | ||
361 | ret = cxd2820r_read_ber_c(fe, ber); | ||
362 | break; | ||
363 | default: | ||
364 | ret = -EINVAL; | ||
365 | break; | ||
366 | } | ||
367 | return ret; | ||
368 | } | 228 | } |
369 | 229 | ||
370 | static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | 230 | static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength) |
371 | { | 231 | { |
372 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 232 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
373 | int ret; | 233 | struct i2c_client *client = priv->client[0]; |
234 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
374 | 235 | ||
375 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 236 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
376 | fe->dtv_property_cache.delivery_system); | ||
377 | 237 | ||
378 | switch (fe->dtv_property_cache.delivery_system) { | 238 | if (c->strength.stat[0].scale == FE_SCALE_RELATIVE) |
379 | case SYS_DVBT: | 239 | *strength = c->strength.stat[0].uvalue; |
380 | ret = cxd2820r_read_signal_strength_t(fe, strength); | 240 | else |
381 | break; | 241 | *strength = 0; |
382 | case SYS_DVBT2: | 242 | |
383 | ret = cxd2820r_read_signal_strength_t2(fe, strength); | 243 | return 0; |
384 | break; | ||
385 | case SYS_DVBC_ANNEX_A: | ||
386 | ret = cxd2820r_read_signal_strength_c(fe, strength); | ||
387 | break; | ||
388 | default: | ||
389 | ret = -EINVAL; | ||
390 | break; | ||
391 | } | ||
392 | return ret; | ||
393 | } | 244 | } |
394 | 245 | ||
395 | static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr) | 246 | static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr) |
396 | { | 247 | { |
397 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 248 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
398 | int ret; | 249 | struct i2c_client *client = priv->client[0]; |
250 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
399 | 251 | ||
400 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 252 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
401 | fe->dtv_property_cache.delivery_system); | ||
402 | 253 | ||
403 | switch (fe->dtv_property_cache.delivery_system) { | 254 | if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL) |
404 | case SYS_DVBT: | 255 | *snr = div_s64(c->cnr.stat[0].svalue, 100); |
405 | ret = cxd2820r_read_snr_t(fe, snr); | 256 | else |
406 | break; | 257 | *snr = 0; |
407 | case SYS_DVBT2: | 258 | |
408 | ret = cxd2820r_read_snr_t2(fe, snr); | 259 | return 0; |
409 | break; | ||
410 | case SYS_DVBC_ANNEX_A: | ||
411 | ret = cxd2820r_read_snr_c(fe, snr); | ||
412 | break; | ||
413 | default: | ||
414 | ret = -EINVAL; | ||
415 | break; | ||
416 | } | ||
417 | return ret; | ||
418 | } | 260 | } |
419 | 261 | ||
420 | static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | 262 | static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) |
421 | { | 263 | { |
422 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 264 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
423 | int ret; | 265 | struct i2c_client *client = priv->client[0]; |
266 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
424 | 267 | ||
425 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 268 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
426 | fe->dtv_property_cache.delivery_system); | ||
427 | 269 | ||
428 | switch (fe->dtv_property_cache.delivery_system) { | 270 | *ucblocks = 0; |
429 | case SYS_DVBT: | 271 | |
430 | ret = cxd2820r_read_ucblocks_t(fe, ucblocks); | 272 | return 0; |
431 | break; | ||
432 | case SYS_DVBT2: | ||
433 | ret = cxd2820r_read_ucblocks_t2(fe, ucblocks); | ||
434 | break; | ||
435 | case SYS_DVBC_ANNEX_A: | ||
436 | ret = cxd2820r_read_ucblocks_c(fe, ucblocks); | ||
437 | break; | ||
438 | default: | ||
439 | ret = -EINVAL; | ||
440 | break; | ||
441 | } | ||
442 | return ret; | ||
443 | } | 273 | } |
444 | 274 | ||
445 | static int cxd2820r_init(struct dvb_frontend *fe) | 275 | static int cxd2820r_init(struct dvb_frontend *fe) |
@@ -450,12 +280,13 @@ static int cxd2820r_init(struct dvb_frontend *fe) | |||
450 | static int cxd2820r_sleep(struct dvb_frontend *fe) | 280 | static int cxd2820r_sleep(struct dvb_frontend *fe) |
451 | { | 281 | { |
452 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 282 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
283 | struct i2c_client *client = priv->client[0]; | ||
284 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
453 | int ret; | 285 | int ret; |
454 | 286 | ||
455 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 287 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
456 | fe->dtv_property_cache.delivery_system); | ||
457 | 288 | ||
458 | switch (fe->dtv_property_cache.delivery_system) { | 289 | switch (c->delivery_system) { |
459 | case SYS_DVBT: | 290 | case SYS_DVBT: |
460 | ret = cxd2820r_sleep_t(fe); | 291 | ret = cxd2820r_sleep_t(fe); |
461 | break; | 292 | break; |
@@ -476,12 +307,13 @@ static int cxd2820r_get_tune_settings(struct dvb_frontend *fe, | |||
476 | struct dvb_frontend_tune_settings *s) | 307 | struct dvb_frontend_tune_settings *s) |
477 | { | 308 | { |
478 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 309 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
310 | struct i2c_client *client = priv->client[0]; | ||
311 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
479 | int ret; | 312 | int ret; |
480 | 313 | ||
481 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 314 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
482 | fe->dtv_property_cache.delivery_system); | ||
483 | 315 | ||
484 | switch (fe->dtv_property_cache.delivery_system) { | 316 | switch (c->delivery_system) { |
485 | case SYS_DVBT: | 317 | case SYS_DVBT: |
486 | ret = cxd2820r_get_tune_settings_t(fe, s); | 318 | ret = cxd2820r_get_tune_settings_t(fe, s); |
487 | break; | 319 | break; |
@@ -501,12 +333,12 @@ static int cxd2820r_get_tune_settings(struct dvb_frontend *fe, | |||
501 | static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | 333 | static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) |
502 | { | 334 | { |
503 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 335 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
336 | struct i2c_client *client = priv->client[0]; | ||
504 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 337 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
505 | int ret, i; | 338 | int ret, i; |
506 | enum fe_status status = 0; | 339 | enum fe_status status = 0; |
507 | 340 | ||
508 | dev_dbg(&priv->i2c->dev, "%s: delsys=%d\n", __func__, | 341 | dev_dbg(&client->dev, "delivery_system=%d\n", c->delivery_system); |
509 | fe->dtv_property_cache.delivery_system); | ||
510 | 342 | ||
511 | /* switch between DVB-T and DVB-T2 when tune fails */ | 343 | /* switch between DVB-T and DVB-T2 when tune fails */ |
512 | if (priv->last_tune_failed) { | 344 | if (priv->last_tune_failed) { |
@@ -530,7 +362,6 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
530 | if (ret) | 362 | if (ret) |
531 | goto error; | 363 | goto error; |
532 | 364 | ||
533 | |||
534 | /* frontend lock wait loop count */ | 365 | /* frontend lock wait loop count */ |
535 | switch (priv->delivery_system) { | 366 | switch (priv->delivery_system) { |
536 | case SYS_DVBT: | 367 | case SYS_DVBT: |
@@ -548,7 +379,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
548 | 379 | ||
549 | /* wait frontend lock */ | 380 | /* wait frontend lock */ |
550 | for (; i > 0; i--) { | 381 | for (; i > 0; i--) { |
551 | dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i); | 382 | dev_dbg(&client->dev, "loop=%d\n", i); |
552 | msleep(50); | 383 | msleep(50); |
553 | ret = cxd2820r_read_status(fe, &status); | 384 | ret = cxd2820r_read_status(fe, &status); |
554 | if (ret) | 385 | if (ret) |
@@ -568,7 +399,7 @@ static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe) | |||
568 | } | 399 | } |
569 | 400 | ||
570 | error: | 401 | error: |
571 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 402 | dev_dbg(&client->dev, "failed=%d\n", ret); |
572 | return DVBFE_ALGO_SEARCH_ERROR; | 403 | return DVBFE_ALGO_SEARCH_ERROR; |
573 | } | 404 | } |
574 | 405 | ||
@@ -580,27 +411,23 @@ static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe) | |||
580 | static void cxd2820r_release(struct dvb_frontend *fe) | 411 | static void cxd2820r_release(struct dvb_frontend *fe) |
581 | { | 412 | { |
582 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 413 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
414 | struct i2c_client *client = priv->client[0]; | ||
583 | 415 | ||
584 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); | 416 | dev_dbg(&client->dev, "\n"); |
585 | 417 | ||
586 | #ifdef CONFIG_GPIOLIB | 418 | i2c_unregister_device(client); |
587 | /* remove GPIOs */ | ||
588 | if (priv->gpio_chip.label) | ||
589 | gpiochip_remove(&priv->gpio_chip); | ||
590 | 419 | ||
591 | #endif | ||
592 | kfree(priv); | ||
593 | return; | 420 | return; |
594 | } | 421 | } |
595 | 422 | ||
596 | static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | 423 | static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) |
597 | { | 424 | { |
598 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 425 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
426 | struct i2c_client *client = priv->client[0]; | ||
599 | 427 | ||
600 | dev_dbg(&priv->i2c->dev, "%s: %d\n", __func__, enable); | 428 | dev_dbg_ratelimited(&client->dev, "enable=%d\n", enable); |
601 | 429 | ||
602 | /* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */ | 430 | return regmap_update_bits(priv->regmap[0], 0x00db, 0x01, enable ? 1 : 0); |
603 | return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); | ||
604 | } | 431 | } |
605 | 432 | ||
606 | #ifdef CONFIG_GPIOLIB | 433 | #ifdef CONFIG_GPIOLIB |
@@ -608,9 +435,10 @@ static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr, | |||
608 | int val) | 435 | int val) |
609 | { | 436 | { |
610 | struct cxd2820r_priv *priv = gpiochip_get_data(chip); | 437 | struct cxd2820r_priv *priv = gpiochip_get_data(chip); |
438 | struct i2c_client *client = priv->client[0]; | ||
611 | u8 gpio[GPIO_COUNT]; | 439 | u8 gpio[GPIO_COUNT]; |
612 | 440 | ||
613 | dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val); | 441 | dev_dbg(&client->dev, "nr=%u val=%d\n", nr, val); |
614 | 442 | ||
615 | memcpy(gpio, priv->gpio, sizeof(gpio)); | 443 | memcpy(gpio, priv->gpio, sizeof(gpio)); |
616 | gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2); | 444 | gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2); |
@@ -621,9 +449,10 @@ static int cxd2820r_gpio_direction_output(struct gpio_chip *chip, unsigned nr, | |||
621 | static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val) | 449 | static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val) |
622 | { | 450 | { |
623 | struct cxd2820r_priv *priv = gpiochip_get_data(chip); | 451 | struct cxd2820r_priv *priv = gpiochip_get_data(chip); |
452 | struct i2c_client *client = priv->client[0]; | ||
624 | u8 gpio[GPIO_COUNT]; | 453 | u8 gpio[GPIO_COUNT]; |
625 | 454 | ||
626 | dev_dbg(&priv->i2c->dev, "%s: nr=%d val=%d\n", __func__, nr, val); | 455 | dev_dbg(&client->dev, "nr=%u val=%d\n", nr, val); |
627 | 456 | ||
628 | memcpy(gpio, priv->gpio, sizeof(gpio)); | 457 | memcpy(gpio, priv->gpio, sizeof(gpio)); |
629 | gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2); | 458 | gpio[nr] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | (val << 2); |
@@ -636,8 +465,9 @@ static void cxd2820r_gpio_set(struct gpio_chip *chip, unsigned nr, int val) | |||
636 | static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr) | 465 | static int cxd2820r_gpio_get(struct gpio_chip *chip, unsigned nr) |
637 | { | 466 | { |
638 | struct cxd2820r_priv *priv = gpiochip_get_data(chip); | 467 | struct cxd2820r_priv *priv = gpiochip_get_data(chip); |
468 | struct i2c_client *client = priv->client[0]; | ||
639 | 469 | ||
640 | dev_dbg(&priv->i2c->dev, "%s: nr=%d\n", __func__, nr); | 470 | dev_dbg(&client->dev, "nr=%u\n", nr); |
641 | 471 | ||
642 | return (priv->gpio[nr] >> 2) & 0x01; | 472 | return (priv->gpio[nr] >> 2) & 0x01; |
643 | } | 473 | } |
@@ -689,52 +519,163 @@ static const struct dvb_frontend_ops cxd2820r_ops = { | |||
689 | .read_signal_strength = cxd2820r_read_signal_strength, | 519 | .read_signal_strength = cxd2820r_read_signal_strength, |
690 | }; | 520 | }; |
691 | 521 | ||
692 | struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, | 522 | /* |
693 | struct i2c_adapter *i2c, int *gpio_chip_base | 523 | * XXX: That is wrapper to cxd2820r_probe() via driver core in order to provide |
694 | ) | 524 | * proper I2C client for legacy media attach binding. |
525 | * New users must use I2C client binding directly! | ||
526 | */ | ||
527 | struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *config, | ||
528 | struct i2c_adapter *adapter, | ||
529 | int *gpio_chip_base) | ||
530 | { | ||
531 | struct i2c_client *client; | ||
532 | struct i2c_board_info board_info; | ||
533 | struct cxd2820r_platform_data pdata; | ||
534 | |||
535 | pdata.ts_mode = config->ts_mode; | ||
536 | pdata.ts_clk_inv = config->ts_clock_inv; | ||
537 | pdata.if_agc_polarity = config->if_agc_polarity; | ||
538 | pdata.spec_inv = config->spec_inv; | ||
539 | pdata.gpio_chip_base = &gpio_chip_base; | ||
540 | pdata.attach_in_use = true; | ||
541 | |||
542 | memset(&board_info, 0, sizeof(board_info)); | ||
543 | strlcpy(board_info.type, "cxd2820r", I2C_NAME_SIZE); | ||
544 | board_info.addr = config->i2c_address; | ||
545 | board_info.platform_data = &pdata; | ||
546 | client = i2c_new_device(adapter, &board_info); | ||
547 | if (!client || !client->dev.driver) | ||
548 | return NULL; | ||
549 | |||
550 | return pdata.get_dvb_frontend(client); | ||
551 | } | ||
552 | EXPORT_SYMBOL(cxd2820r_attach); | ||
553 | |||
554 | static struct dvb_frontend *cxd2820r_get_dvb_frontend(struct i2c_client *client) | ||
555 | { | ||
556 | struct cxd2820r_priv *priv = i2c_get_clientdata(client); | ||
557 | |||
558 | dev_dbg(&client->dev, "\n"); | ||
559 | |||
560 | return &priv->fe; | ||
561 | } | ||
562 | |||
563 | static int cxd2820r_probe(struct i2c_client *client, | ||
564 | const struct i2c_device_id *id) | ||
695 | { | 565 | { |
566 | struct cxd2820r_platform_data *pdata = client->dev.platform_data; | ||
696 | struct cxd2820r_priv *priv; | 567 | struct cxd2820r_priv *priv; |
697 | int ret; | 568 | int ret, *gpio_chip_base; |
698 | u8 tmp; | 569 | unsigned int utmp; |
570 | static const struct regmap_range_cfg regmap_range_cfg0[] = { | ||
571 | { | ||
572 | .range_min = 0x0000, | ||
573 | .range_max = 0x3fff, | ||
574 | .selector_reg = 0x00, | ||
575 | .selector_mask = 0xff, | ||
576 | .selector_shift = 0, | ||
577 | .window_start = 0x00, | ||
578 | .window_len = 0x100, | ||
579 | }, | ||
580 | }; | ||
581 | static const struct regmap_range_cfg regmap_range_cfg1[] = { | ||
582 | { | ||
583 | .range_min = 0x0000, | ||
584 | .range_max = 0x01ff, | ||
585 | .selector_reg = 0x00, | ||
586 | .selector_mask = 0xff, | ||
587 | .selector_shift = 0, | ||
588 | .window_start = 0x00, | ||
589 | .window_len = 0x100, | ||
590 | }, | ||
591 | }; | ||
592 | static const struct regmap_config regmap_config0 = { | ||
593 | .reg_bits = 8, | ||
594 | .val_bits = 8, | ||
595 | .max_register = 0x3fff, | ||
596 | .ranges = regmap_range_cfg0, | ||
597 | .num_ranges = ARRAY_SIZE(regmap_range_cfg0), | ||
598 | .cache_type = REGCACHE_NONE, | ||
599 | }; | ||
600 | static const struct regmap_config regmap_config1 = { | ||
601 | .reg_bits = 8, | ||
602 | .val_bits = 8, | ||
603 | .max_register = 0x01ff, | ||
604 | .ranges = regmap_range_cfg1, | ||
605 | .num_ranges = ARRAY_SIZE(regmap_range_cfg1), | ||
606 | .cache_type = REGCACHE_NONE, | ||
607 | }; | ||
608 | |||
609 | dev_dbg(&client->dev, "\n"); | ||
699 | 610 | ||
700 | priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL); | 611 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
701 | if (!priv) { | 612 | if (!priv) { |
702 | ret = -ENOMEM; | 613 | ret = -ENOMEM; |
703 | dev_err(&i2c->dev, "%s: kzalloc() failed\n", | 614 | goto err; |
704 | KBUILD_MODNAME); | ||
705 | goto error; | ||
706 | } | 615 | } |
707 | 616 | ||
708 | priv->i2c = i2c; | 617 | priv->client[0] = client; |
709 | memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config)); | 618 | priv->i2c = client->adapter; |
710 | memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(struct dvb_frontend_ops)); | 619 | priv->ts_mode = pdata->ts_mode; |
711 | priv->fe.demodulator_priv = priv; | 620 | priv->ts_clk_inv = pdata->ts_clk_inv; |
621 | priv->if_agc_polarity = pdata->if_agc_polarity; | ||
622 | priv->spec_inv = pdata->spec_inv; | ||
623 | gpio_chip_base = *pdata->gpio_chip_base; | ||
624 | priv->regmap[0] = regmap_init_i2c(priv->client[0], ®map_config0); | ||
625 | if (IS_ERR(priv->regmap[0])) { | ||
626 | ret = PTR_ERR(priv->regmap[0]); | ||
627 | goto err_kfree; | ||
628 | } | ||
712 | 629 | ||
713 | priv->bank[0] = priv->bank[1] = 0xff; | 630 | /* Check demod answers with correct chip id */ |
714 | ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp); | 631 | ret = regmap_read(priv->regmap[0], 0x00fd, &utmp); |
715 | dev_dbg(&priv->i2c->dev, "%s: chip id=%02x\n", __func__, tmp); | 632 | if (ret) |
716 | if (ret || tmp != 0xe1) | 633 | goto err_regmap_0_regmap_exit; |
717 | goto error; | 634 | |
635 | dev_dbg(&client->dev, "chip_id=%02x\n", utmp); | ||
636 | |||
637 | if (utmp != 0xe1) { | ||
638 | ret = -ENODEV; | ||
639 | goto err_regmap_0_regmap_exit; | ||
640 | } | ||
641 | |||
642 | /* | ||
643 | * Chip has two I2C addresses for different register banks. We register | ||
644 | * one dummy I2C client in in order to get own I2C client for each | ||
645 | * register bank. | ||
646 | */ | ||
647 | priv->client[1] = i2c_new_dummy(client->adapter, client->addr | (1 << 1)); | ||
648 | if (!priv->client[1]) { | ||
649 | ret = -ENODEV; | ||
650 | dev_err(&client->dev, "I2C registration failed\n"); | ||
651 | if (ret) | ||
652 | goto err_regmap_0_regmap_exit; | ||
653 | } | ||
654 | |||
655 | priv->regmap[1] = regmap_init_i2c(priv->client[1], ®map_config1); | ||
656 | if (IS_ERR(priv->regmap[1])) { | ||
657 | ret = PTR_ERR(priv->regmap[1]); | ||
658 | goto err_client_1_i2c_unregister_device; | ||
659 | } | ||
718 | 660 | ||
719 | if (gpio_chip_base) { | 661 | if (gpio_chip_base) { |
720 | #ifdef CONFIG_GPIOLIB | 662 | #ifdef CONFIG_GPIOLIB |
721 | /* add GPIOs */ | 663 | /* Add GPIOs */ |
722 | priv->gpio_chip.label = KBUILD_MODNAME; | 664 | priv->gpio_chip.label = KBUILD_MODNAME; |
723 | priv->gpio_chip.parent = &priv->i2c->dev; | 665 | priv->gpio_chip.parent = &client->dev; |
724 | priv->gpio_chip.owner = THIS_MODULE; | 666 | priv->gpio_chip.owner = THIS_MODULE; |
725 | priv->gpio_chip.direction_output = | 667 | priv->gpio_chip.direction_output = cxd2820r_gpio_direction_output; |
726 | cxd2820r_gpio_direction_output; | ||
727 | priv->gpio_chip.set = cxd2820r_gpio_set; | 668 | priv->gpio_chip.set = cxd2820r_gpio_set; |
728 | priv->gpio_chip.get = cxd2820r_gpio_get; | 669 | priv->gpio_chip.get = cxd2820r_gpio_get; |
729 | priv->gpio_chip.base = -1; /* dynamic allocation */ | 670 | priv->gpio_chip.base = -1; /* Dynamic allocation */ |
730 | priv->gpio_chip.ngpio = GPIO_COUNT; | 671 | priv->gpio_chip.ngpio = GPIO_COUNT; |
731 | priv->gpio_chip.can_sleep = 1; | 672 | priv->gpio_chip.can_sleep = 1; |
732 | ret = gpiochip_add_data(&priv->gpio_chip, priv); | 673 | ret = gpiochip_add_data(&priv->gpio_chip, priv); |
733 | if (ret) | 674 | if (ret) |
734 | goto error; | 675 | goto err_regmap_1_regmap_exit; |
735 | 676 | ||
736 | dev_dbg(&priv->i2c->dev, "%s: gpio_chip.base=%d\n", __func__, | 677 | dev_dbg(&client->dev, "gpio_chip.base=%d\n", |
737 | priv->gpio_chip.base); | 678 | priv->gpio_chip.base); |
738 | 679 | ||
739 | *gpio_chip_base = priv->gpio_chip.base; | 680 | *gpio_chip_base = priv->gpio_chip.base; |
740 | #else | 681 | #else |
@@ -748,17 +689,73 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, | |||
748 | gpio[2] = 0; | 689 | gpio[2] = 0; |
749 | ret = cxd2820r_gpio(&priv->fe, gpio); | 690 | ret = cxd2820r_gpio(&priv->fe, gpio); |
750 | if (ret) | 691 | if (ret) |
751 | goto error; | 692 | goto err_regmap_1_regmap_exit; |
752 | #endif | 693 | #endif |
753 | } | 694 | } |
754 | 695 | ||
755 | return &priv->fe; | 696 | /* Create dvb frontend */ |
756 | error: | 697 | memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof(priv->fe.ops)); |
757 | dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); | 698 | if (!pdata->attach_in_use) |
699 | priv->fe.ops.release = NULL; | ||
700 | priv->fe.demodulator_priv = priv; | ||
701 | i2c_set_clientdata(client, priv); | ||
702 | |||
703 | /* Setup callbacks */ | ||
704 | pdata->get_dvb_frontend = cxd2820r_get_dvb_frontend; | ||
705 | |||
706 | dev_info(&client->dev, "Sony CXD2820R successfully identified\n"); | ||
707 | |||
708 | return 0; | ||
709 | err_regmap_1_regmap_exit: | ||
710 | regmap_exit(priv->regmap[1]); | ||
711 | err_client_1_i2c_unregister_device: | ||
712 | i2c_unregister_device(priv->client[1]); | ||
713 | err_regmap_0_regmap_exit: | ||
714 | regmap_exit(priv->regmap[0]); | ||
715 | err_kfree: | ||
758 | kfree(priv); | 716 | kfree(priv); |
759 | return NULL; | 717 | err: |
718 | dev_dbg(&client->dev, "failed=%d\n", ret); | ||
719 | return ret; | ||
760 | } | 720 | } |
761 | EXPORT_SYMBOL(cxd2820r_attach); | 721 | |
722 | static int cxd2820r_remove(struct i2c_client *client) | ||
723 | { | ||
724 | struct cxd2820r_priv *priv = i2c_get_clientdata(client); | ||
725 | |||
726 | dev_dbg(&client->dev, "\n"); | ||
727 | |||
728 | #ifdef CONFIG_GPIOLIB | ||
729 | if (priv->gpio_chip.label) | ||
730 | gpiochip_remove(&priv->gpio_chip); | ||
731 | #endif | ||
732 | regmap_exit(priv->regmap[1]); | ||
733 | i2c_unregister_device(priv->client[1]); | ||
734 | |||
735 | regmap_exit(priv->regmap[0]); | ||
736 | |||
737 | kfree(priv); | ||
738 | |||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static const struct i2c_device_id cxd2820r_id_table[] = { | ||
743 | {"cxd2820r", 0}, | ||
744 | {} | ||
745 | }; | ||
746 | MODULE_DEVICE_TABLE(i2c, cxd2820r_id_table); | ||
747 | |||
748 | static struct i2c_driver cxd2820r_driver = { | ||
749 | .driver = { | ||
750 | .name = "cxd2820r", | ||
751 | .suppress_bind_attrs = true, | ||
752 | }, | ||
753 | .probe = cxd2820r_probe, | ||
754 | .remove = cxd2820r_remove, | ||
755 | .id_table = cxd2820r_id_table, | ||
756 | }; | ||
757 | |||
758 | module_i2c_driver(cxd2820r_driver); | ||
762 | 759 | ||
763 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | 760 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); |
764 | MODULE_DESCRIPTION("Sony CXD2820R demodulator driver"); | 761 | MODULE_DESCRIPTION("Sony CXD2820R demodulator driver"); |
diff --git a/drivers/media/dvb-frontends/cxd2820r_priv.h b/drivers/media/dvb-frontends/cxd2820r_priv.h index e31c48e53097..0d096206ac66 100644 --- a/drivers/media/dvb-frontends/cxd2820r_priv.h +++ b/drivers/media/dvb-frontends/cxd2820r_priv.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #include "dvb_math.h" | 27 | #include "dvb_math.h" |
28 | #include "cxd2820r.h" | 28 | #include "cxd2820r.h" |
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/math64.h> | ||
31 | #include <linux/regmap.h> | ||
30 | 32 | ||
31 | struct reg_val_mask { | 33 | struct reg_val_mask { |
32 | u32 reg; | 34 | u32 reg; |
@@ -34,14 +36,23 @@ struct reg_val_mask { | |||
34 | u8 mask; | 36 | u8 mask; |
35 | }; | 37 | }; |
36 | 38 | ||
39 | #define CXD2820R_CLK 41000000 | ||
40 | |||
37 | struct cxd2820r_priv { | 41 | struct cxd2820r_priv { |
42 | struct i2c_client *client[2]; | ||
43 | struct regmap *regmap[2]; | ||
38 | struct i2c_adapter *i2c; | 44 | struct i2c_adapter *i2c; |
39 | struct dvb_frontend fe; | 45 | struct dvb_frontend fe; |
40 | struct cxd2820r_config cfg; | 46 | u8 ts_mode; |
47 | bool ts_clk_inv; | ||
48 | bool if_agc_polarity; | ||
49 | bool spec_inv; | ||
50 | |||
51 | u64 post_bit_error_prev_dvbv3; | ||
52 | u64 post_bit_error; | ||
41 | 53 | ||
42 | bool ber_running; | 54 | bool ber_running; |
43 | 55 | ||
44 | u8 bank[2]; | ||
45 | #define GPIO_COUNT 3 | 56 | #define GPIO_COUNT 3 |
46 | u8 gpio[GPIO_COUNT]; | 57 | u8 gpio[GPIO_COUNT]; |
47 | #ifdef CONFIG_GPIOLIB | 58 | #ifdef CONFIG_GPIOLIB |
@@ -58,6 +69,9 @@ extern int cxd2820r_debug; | |||
58 | 69 | ||
59 | int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio); | 70 | int cxd2820r_gpio(struct dvb_frontend *fe, u8 *gpio); |
60 | 71 | ||
72 | int cxd2820r_wr_reg_val_mask_tab(struct cxd2820r_priv *priv, | ||
73 | const struct reg_val_mask *tab, int tab_len); | ||
74 | |||
61 | int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, | 75 | int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val, |
62 | u8 mask); | 76 | u8 mask); |
63 | 77 | ||
@@ -83,14 +97,6 @@ int cxd2820r_set_frontend_c(struct dvb_frontend *fe); | |||
83 | 97 | ||
84 | int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status); | 98 | int cxd2820r_read_status_c(struct dvb_frontend *fe, enum fe_status *status); |
85 | 99 | ||
86 | int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber); | ||
87 | |||
88 | int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength); | ||
89 | |||
90 | int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr); | ||
91 | |||
92 | int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks); | ||
93 | |||
94 | int cxd2820r_init_c(struct dvb_frontend *fe); | 100 | int cxd2820r_init_c(struct dvb_frontend *fe); |
95 | 101 | ||
96 | int cxd2820r_sleep_c(struct dvb_frontend *fe); | 102 | int cxd2820r_sleep_c(struct dvb_frontend *fe); |
@@ -107,14 +113,6 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe); | |||
107 | 113 | ||
108 | int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status); | 114 | int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status); |
109 | 115 | ||
110 | int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber); | ||
111 | |||
112 | int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength); | ||
113 | |||
114 | int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr); | ||
115 | |||
116 | int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks); | ||
117 | |||
118 | int cxd2820r_init_t(struct dvb_frontend *fe); | 116 | int cxd2820r_init_t(struct dvb_frontend *fe); |
119 | 117 | ||
120 | int cxd2820r_sleep_t(struct dvb_frontend *fe); | 118 | int cxd2820r_sleep_t(struct dvb_frontend *fe); |
@@ -131,14 +129,6 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe); | |||
131 | 129 | ||
132 | int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status); | 130 | int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status); |
133 | 131 | ||
134 | int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber); | ||
135 | |||
136 | int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength); | ||
137 | |||
138 | int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr); | ||
139 | |||
140 | int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks); | ||
141 | |||
142 | int cxd2820r_init_t2(struct dvb_frontend *fe); | 132 | int cxd2820r_init_t2(struct dvb_frontend *fe); |
143 | 133 | ||
144 | int cxd2820r_sleep_t2(struct dvb_frontend *fe); | 134 | int cxd2820r_sleep_t2(struct dvb_frontend *fe); |
diff --git a/drivers/media/dvb-frontends/cxd2820r_t.c b/drivers/media/dvb-frontends/cxd2820r_t.c index 75ce7d8ded00..c2e7caf9b010 100644 --- a/drivers/media/dvb-frontends/cxd2820r_t.c +++ b/drivers/media/dvb-frontends/cxd2820r_t.c | |||
@@ -24,10 +24,11 @@ | |||
24 | int cxd2820r_set_frontend_t(struct dvb_frontend *fe) | 24 | int cxd2820r_set_frontend_t(struct dvb_frontend *fe) |
25 | { | 25 | { |
26 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 26 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
27 | struct i2c_client *client = priv->client[0]; | ||
27 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | 28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
28 | int ret, i, bw_i; | 29 | int ret, bw_i; |
29 | u32 if_freq, if_ctl; | 30 | unsigned int utmp; |
30 | u64 num; | 31 | u32 if_frequency; |
31 | u8 buf[3], bw_param; | 32 | u8 buf[3], bw_param; |
32 | u8 bw_params1[][5] = { | 33 | u8 bw_params1[][5] = { |
33 | { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */ | 34 | { 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */ |
@@ -45,9 +46,9 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) | |||
45 | { 0x00085, 0x07, 0xff }, | 46 | { 0x00085, 0x07, 0xff }, |
46 | { 0x00088, 0x01, 0xff }, | 47 | { 0x00088, 0x01, 0xff }, |
47 | 48 | ||
48 | { 0x00070, priv->cfg.ts_mode, 0xff }, | 49 | { 0x00070, priv->ts_mode, 0xff }, |
49 | { 0x00071, !priv->cfg.ts_clock_inv << 4, 0x10 }, | 50 | { 0x00071, !priv->ts_clk_inv << 4, 0x10 }, |
50 | { 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 }, | 51 | { 0x000cb, priv->if_agc_polarity << 6, 0x40 }, |
51 | { 0x000a5, 0x00, 0x01 }, | 52 | { 0x000a5, 0x00, 0x01 }, |
52 | { 0x00082, 0x20, 0x60 }, | 53 | { 0x00082, 0x20, 0x60 }, |
53 | { 0x000c2, 0xc3, 0xff }, | 54 | { 0x000c2, 0xc3, 0xff }, |
@@ -55,8 +56,10 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) | |||
55 | { 0x00427, 0x41, 0xff }, | 56 | { 0x00427, 0x41, 0xff }, |
56 | }; | 57 | }; |
57 | 58 | ||
58 | dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", __func__, | 59 | dev_dbg(&client->dev, |
59 | c->frequency, c->bandwidth_hz); | 60 | "delivery_system=%d modulation=%d frequency=%u bandwidth_hz=%u inversion=%d\n", |
61 | c->delivery_system, c->modulation, c->frequency, | ||
62 | c->bandwidth_hz, c->inversion); | ||
60 | 63 | ||
61 | switch (c->bandwidth_hz) { | 64 | switch (c->bandwidth_hz) { |
62 | case 6000000: | 65 | case 6000000: |
@@ -80,12 +83,9 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) | |||
80 | fe->ops.tuner_ops.set_params(fe); | 83 | fe->ops.tuner_ops.set_params(fe); |
81 | 84 | ||
82 | if (priv->delivery_system != SYS_DVBT) { | 85 | if (priv->delivery_system != SYS_DVBT) { |
83 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | 86 | ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); |
84 | ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, | 87 | if (ret) |
85 | tab[i].val, tab[i].mask); | 88 | goto error; |
86 | if (ret) | ||
87 | goto error; | ||
88 | } | ||
89 | } | 89 | } |
90 | 90 | ||
91 | priv->delivery_system = SYS_DVBT; | 91 | priv->delivery_system = SYS_DVBT; |
@@ -93,48 +93,46 @@ int cxd2820r_set_frontend_t(struct dvb_frontend *fe) | |||
93 | 93 | ||
94 | /* program IF frequency */ | 94 | /* program IF frequency */ |
95 | if (fe->ops.tuner_ops.get_if_frequency) { | 95 | if (fe->ops.tuner_ops.get_if_frequency) { |
96 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); | 96 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); |
97 | if (ret) | 97 | if (ret) |
98 | goto error; | 98 | goto error; |
99 | } else | 99 | dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency); |
100 | if_freq = 0; | 100 | } else { |
101 | 101 | ret = -EINVAL; | |
102 | dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq); | 102 | goto error; |
103 | 103 | } | |
104 | num = if_freq / 1000; /* Hz => kHz */ | ||
105 | num *= 0x1000000; | ||
106 | if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000); | ||
107 | buf[0] = ((if_ctl >> 16) & 0xff); | ||
108 | buf[1] = ((if_ctl >> 8) & 0xff); | ||
109 | buf[2] = ((if_ctl >> 0) & 0xff); | ||
110 | 104 | ||
111 | ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3); | 105 | utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, CXD2820R_CLK); |
106 | buf[0] = (utmp >> 16) & 0xff; | ||
107 | buf[1] = (utmp >> 8) & 0xff; | ||
108 | buf[2] = (utmp >> 0) & 0xff; | ||
109 | ret = regmap_bulk_write(priv->regmap[0], 0x00b6, buf, 3); | ||
112 | if (ret) | 110 | if (ret) |
113 | goto error; | 111 | goto error; |
114 | 112 | ||
115 | ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[bw_i], 5); | 113 | ret = regmap_bulk_write(priv->regmap[0], 0x009f, bw_params1[bw_i], 5); |
116 | if (ret) | 114 | if (ret) |
117 | goto error; | 115 | goto error; |
118 | 116 | ||
119 | ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0); | 117 | ret = regmap_update_bits(priv->regmap[0], 0x00d7, 0xc0, bw_param << 6); |
120 | if (ret) | 118 | if (ret) |
121 | goto error; | 119 | goto error; |
122 | 120 | ||
123 | ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[bw_i], 2); | 121 | ret = regmap_bulk_write(priv->regmap[0], 0x00d9, bw_params2[bw_i], 2); |
124 | if (ret) | 122 | if (ret) |
125 | goto error; | 123 | goto error; |
126 | 124 | ||
127 | ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08); | 125 | ret = regmap_write(priv->regmap[0], 0x00ff, 0x08); |
128 | if (ret) | 126 | if (ret) |
129 | goto error; | 127 | goto error; |
130 | 128 | ||
131 | ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01); | 129 | ret = regmap_write(priv->regmap[0], 0x00fe, 0x01); |
132 | if (ret) | 130 | if (ret) |
133 | goto error; | 131 | goto error; |
134 | 132 | ||
135 | return ret; | 133 | return ret; |
136 | error: | 134 | error: |
137 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 135 | dev_dbg(&client->dev, "failed=%d\n", ret); |
138 | return ret; | 136 | return ret; |
139 | } | 137 | } |
140 | 138 | ||
@@ -142,10 +140,14 @@ int cxd2820r_get_frontend_t(struct dvb_frontend *fe, | |||
142 | struct dtv_frontend_properties *c) | 140 | struct dtv_frontend_properties *c) |
143 | { | 141 | { |
144 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 142 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
143 | struct i2c_client *client = priv->client[0]; | ||
145 | int ret; | 144 | int ret; |
145 | unsigned int utmp; | ||
146 | u8 buf[2]; | 146 | u8 buf[2]; |
147 | 147 | ||
148 | ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf)); | 148 | dev_dbg(&client->dev, "\n"); |
149 | |||
150 | ret = regmap_bulk_read(priv->regmap[0], 0x002f, buf, sizeof(buf)); | ||
149 | if (ret) | 151 | if (ret) |
150 | goto error; | 152 | goto error; |
151 | 153 | ||
@@ -236,11 +238,11 @@ int cxd2820r_get_frontend_t(struct dvb_frontend *fe, | |||
236 | break; | 238 | break; |
237 | } | 239 | } |
238 | 240 | ||
239 | ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]); | 241 | ret = regmap_read(priv->regmap[0], 0x07c6, &utmp); |
240 | if (ret) | 242 | if (ret) |
241 | goto error; | 243 | goto error; |
242 | 244 | ||
243 | switch ((buf[0] >> 0) & 0x01) { | 245 | switch ((utmp >> 0) & 0x01) { |
244 | case 0: | 246 | case 0: |
245 | c->inversion = INVERSION_OFF; | 247 | c->inversion = INVERSION_OFF; |
246 | break; | 248 | break; |
@@ -251,169 +253,158 @@ int cxd2820r_get_frontend_t(struct dvb_frontend *fe, | |||
251 | 253 | ||
252 | return ret; | 254 | return ret; |
253 | error: | 255 | error: |
254 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 256 | dev_dbg(&client->dev, "failed=%d\n", ret); |
255 | return ret; | ||
256 | } | ||
257 | |||
258 | int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber) | ||
259 | { | ||
260 | struct cxd2820r_priv *priv = fe->demodulator_priv; | ||
261 | int ret; | ||
262 | u8 buf[3], start_ber = 0; | ||
263 | *ber = 0; | ||
264 | |||
265 | if (priv->ber_running) { | ||
266 | ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf)); | ||
267 | if (ret) | ||
268 | goto error; | ||
269 | |||
270 | if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) { | ||
271 | *ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0]; | ||
272 | start_ber = 1; | ||
273 | } | ||
274 | } else { | ||
275 | priv->ber_running = true; | ||
276 | start_ber = 1; | ||
277 | } | ||
278 | |||
279 | if (start_ber) { | ||
280 | /* (re)start BER */ | ||
281 | ret = cxd2820r_wr_reg(priv, 0x00079, 0x01); | ||
282 | if (ret) | ||
283 | goto error; | ||
284 | } | ||
285 | |||
286 | return ret; | ||
287 | error: | ||
288 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
289 | return ret; | 257 | return ret; |
290 | } | 258 | } |
291 | 259 | ||
292 | int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, | 260 | int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status) |
293 | u16 *strength) | ||
294 | { | 261 | { |
295 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 262 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
263 | struct i2c_client *client = priv->client[0]; | ||
264 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
296 | int ret; | 265 | int ret; |
297 | u8 buf[2]; | 266 | unsigned int utmp, utmp1, utmp2; |
298 | u16 tmp; | 267 | u8 buf[3]; |
299 | 268 | ||
300 | ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf)); | 269 | /* Lock detection */ |
270 | ret = regmap_bulk_read(priv->regmap[0], 0x0010, &buf[0], 1); | ||
271 | if (ret) | ||
272 | goto error; | ||
273 | ret = regmap_bulk_read(priv->regmap[0], 0x0073, &buf[1], 1); | ||
301 | if (ret) | 274 | if (ret) |
302 | goto error; | 275 | goto error; |
303 | 276 | ||
304 | tmp = (buf[0] & 0x0f) << 8 | buf[1]; | 277 | utmp1 = (buf[0] >> 0) & 0x07; |
305 | tmp = ~tmp & 0x0fff; | 278 | utmp2 = (buf[1] >> 3) & 0x01; |
306 | 279 | ||
307 | /* scale value to 0x0000-0xffff from 0x0000-0x0fff */ | 280 | if (utmp1 == 6 && utmp2 == 1) { |
308 | *strength = tmp * 0xffff / 0x0fff; | 281 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | |
282 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
283 | } else if (utmp1 == 6 || utmp2 == 1) { | ||
284 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
285 | FE_HAS_VITERBI | FE_HAS_SYNC; | ||
286 | } else { | ||
287 | *status = 0; | ||
288 | } | ||
309 | 289 | ||
310 | return ret; | 290 | dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n", |
311 | error: | 291 | *status, 2, buf, utmp1, utmp2); |
312 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
313 | return ret; | ||
314 | } | ||
315 | 292 | ||
316 | int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr) | 293 | /* Signal strength */ |
317 | { | 294 | if (*status & FE_HAS_SIGNAL) { |
318 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 295 | unsigned int strength; |
319 | int ret; | ||
320 | u8 buf[2]; | ||
321 | u16 tmp; | ||
322 | /* report SNR in dB * 10 */ | ||
323 | 296 | ||
324 | ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf)); | 297 | ret = regmap_bulk_read(priv->regmap[0], 0x0026, buf, 2); |
325 | if (ret) | 298 | if (ret) |
326 | goto error; | 299 | goto error; |
327 | 300 | ||
328 | tmp = (buf[0] & 0x1f) << 8 | buf[1]; | 301 | utmp = buf[0] << 8 | buf[1] << 0; |
329 | #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */ | 302 | utmp = ~utmp & 0x0fff; |
330 | if (tmp) | 303 | /* Scale value to 0x0000-0xffff */ |
331 | *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24) | 304 | strength = utmp << 4 | utmp >> 8; |
332 | / 100); | ||
333 | else | ||
334 | *snr = 0; | ||
335 | 305 | ||
336 | dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr, | 306 | c->strength.len = 1; |
337 | tmp); | 307 | c->strength.stat[0].scale = FE_SCALE_RELATIVE; |
308 | c->strength.stat[0].uvalue = strength; | ||
309 | } else { | ||
310 | c->strength.len = 1; | ||
311 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
312 | } | ||
338 | 313 | ||
339 | return ret; | 314 | /* CNR */ |
340 | error: | 315 | if (*status & FE_HAS_VITERBI) { |
341 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 316 | unsigned int cnr; |
342 | return ret; | ||
343 | } | ||
344 | 317 | ||
345 | int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks) | 318 | ret = regmap_bulk_read(priv->regmap[0], 0x002c, buf, 2); |
346 | { | 319 | if (ret) |
347 | *ucblocks = 0; | 320 | goto error; |
348 | /* no way to read ? */ | ||
349 | return 0; | ||
350 | } | ||
351 | 321 | ||
352 | int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status) | 322 | utmp = buf[0] << 8 | buf[1] << 0; |
353 | { | 323 | if (utmp) |
354 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 324 | cnr = div_u64((u64)(intlog10(utmp) |
355 | int ret; | 325 | - intlog10(32000 - utmp) + 55532585) |
356 | u8 buf[4]; | 326 | * 10000, (1 << 24)); |
357 | *status = 0; | 327 | else |
328 | cnr = 0; | ||
329 | |||
330 | c->cnr.len = 1; | ||
331 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
332 | c->cnr.stat[0].svalue = cnr; | ||
333 | } else { | ||
334 | c->cnr.len = 1; | ||
335 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
336 | } | ||
358 | 337 | ||
359 | ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]); | 338 | /* BER */ |
360 | if (ret) | 339 | if (*status & FE_HAS_SYNC) { |
361 | goto error; | 340 | unsigned int post_bit_error; |
341 | bool start_ber; | ||
362 | 342 | ||
363 | if ((buf[0] & 0x07) == 6) { | 343 | if (priv->ber_running) { |
364 | ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]); | 344 | ret = regmap_bulk_read(priv->regmap[0], 0x0076, buf, 3); |
365 | if (ret) | 345 | if (ret) |
366 | goto error; | 346 | goto error; |
367 | 347 | ||
368 | if (((buf[1] >> 3) & 0x01) == 1) { | 348 | if ((buf[2] >> 7) & 0x01) { |
369 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | 349 | post_bit_error = buf[2] << 16 | buf[1] << 8 | |
370 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | 350 | buf[0] << 0; |
351 | post_bit_error &= 0x0fffff; | ||
352 | start_ber = true; | ||
353 | } else { | ||
354 | post_bit_error = 0; | ||
355 | start_ber = false; | ||
356 | } | ||
371 | } else { | 357 | } else { |
372 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | 358 | post_bit_error = 0; |
373 | FE_HAS_VITERBI | FE_HAS_SYNC; | 359 | start_ber = true; |
374 | } | 360 | } |
375 | } else { | ||
376 | ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]); | ||
377 | if (ret) | ||
378 | goto error; | ||
379 | 361 | ||
380 | if ((buf[2] & 0x0f) >= 4) { | 362 | if (start_ber) { |
381 | ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]); | 363 | ret = regmap_write(priv->regmap[0], 0x0079, 0x01); |
382 | if (ret) | 364 | if (ret) |
383 | goto error; | 365 | goto error; |
384 | 366 | priv->ber_running = true; | |
385 | if (((buf[3] >> 4) & 0x01) == 1) | ||
386 | *status |= FE_HAS_SIGNAL; | ||
387 | } | 367 | } |
388 | } | ||
389 | 368 | ||
390 | dev_dbg(&priv->i2c->dev, "%s: lock=%*ph\n", __func__, 4, buf); | 369 | priv->post_bit_error += post_bit_error; |
370 | |||
371 | c->post_bit_error.len = 1; | ||
372 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||
373 | c->post_bit_error.stat[0].uvalue = priv->post_bit_error; | ||
374 | } else { | ||
375 | c->post_bit_error.len = 1; | ||
376 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
377 | } | ||
391 | 378 | ||
392 | return ret; | 379 | return ret; |
393 | error: | 380 | error: |
394 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 381 | dev_dbg(&client->dev, "failed=%d\n", ret); |
395 | return ret; | 382 | return ret; |
396 | } | 383 | } |
397 | 384 | ||
398 | int cxd2820r_init_t(struct dvb_frontend *fe) | 385 | int cxd2820r_init_t(struct dvb_frontend *fe) |
399 | { | 386 | { |
400 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 387 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
388 | struct i2c_client *client = priv->client[0]; | ||
401 | int ret; | 389 | int ret; |
402 | 390 | ||
403 | ret = cxd2820r_wr_reg(priv, 0x00085, 0x07); | 391 | dev_dbg(&client->dev, "\n"); |
392 | |||
393 | ret = regmap_write(priv->regmap[0], 0x0085, 0x07); | ||
404 | if (ret) | 394 | if (ret) |
405 | goto error; | 395 | goto error; |
406 | 396 | ||
407 | return ret; | 397 | return ret; |
408 | error: | 398 | error: |
409 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 399 | dev_dbg(&client->dev, "failed=%d\n", ret); |
410 | return ret; | 400 | return ret; |
411 | } | 401 | } |
412 | 402 | ||
413 | int cxd2820r_sleep_t(struct dvb_frontend *fe) | 403 | int cxd2820r_sleep_t(struct dvb_frontend *fe) |
414 | { | 404 | { |
415 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 405 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
416 | int ret, i; | 406 | struct i2c_client *client = priv->client[0]; |
407 | int ret; | ||
417 | struct reg_val_mask tab[] = { | 408 | struct reg_val_mask tab[] = { |
418 | { 0x000ff, 0x1f, 0xff }, | 409 | { 0x000ff, 0x1f, 0xff }, |
419 | { 0x00085, 0x00, 0xff }, | 410 | { 0x00085, 0x00, 0xff }, |
@@ -422,20 +413,17 @@ int cxd2820r_sleep_t(struct dvb_frontend *fe) | |||
422 | { 0x00080, 0x00, 0xff }, | 413 | { 0x00080, 0x00, 0xff }, |
423 | }; | 414 | }; |
424 | 415 | ||
425 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); | 416 | dev_dbg(&client->dev, "\n"); |
426 | 417 | ||
427 | priv->delivery_system = SYS_UNDEFINED; | 418 | priv->delivery_system = SYS_UNDEFINED; |
428 | 419 | ||
429 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | 420 | ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); |
430 | ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val, | 421 | if (ret) |
431 | tab[i].mask); | 422 | goto error; |
432 | if (ret) | ||
433 | goto error; | ||
434 | } | ||
435 | 423 | ||
436 | return ret; | 424 | return ret; |
437 | error: | 425 | error: |
438 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 426 | dev_dbg(&client->dev, "failed=%d\n", ret); |
439 | return ret; | 427 | return ret; |
440 | } | 428 | } |
441 | 429 | ||
diff --git a/drivers/media/dvb-frontends/cxd2820r_t2.c b/drivers/media/dvb-frontends/cxd2820r_t2.c index 704475676234..e641fde75379 100644 --- a/drivers/media/dvb-frontends/cxd2820r_t2.c +++ b/drivers/media/dvb-frontends/cxd2820r_t2.c | |||
@@ -23,11 +23,12 @@ | |||
23 | 23 | ||
24 | int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) | 24 | int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) |
25 | { | 25 | { |
26 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
27 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 26 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
28 | int ret, i, bw_i; | 27 | struct i2c_client *client = priv->client[0]; |
29 | u32 if_freq, if_ctl; | 28 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; |
30 | u64 num; | 29 | int ret, bw_i; |
30 | unsigned int utmp; | ||
31 | u32 if_frequency; | ||
31 | u8 buf[3], bw_param; | 32 | u8 buf[3], bw_param; |
32 | u8 bw_params1[][5] = { | 33 | u8 bw_params1[][5] = { |
33 | { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */ | 34 | { 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */ |
@@ -45,10 +46,10 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) | |||
45 | { 0x0207f, 0x2a, 0xff }, | 46 | { 0x0207f, 0x2a, 0xff }, |
46 | { 0x02082, 0x0a, 0xff }, | 47 | { 0x02082, 0x0a, 0xff }, |
47 | { 0x02083, 0x0a, 0xff }, | 48 | { 0x02083, 0x0a, 0xff }, |
48 | { 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 }, | 49 | { 0x020cb, priv->if_agc_polarity << 6, 0x40 }, |
49 | { 0x02070, priv->cfg.ts_mode, 0xff }, | 50 | { 0x02070, priv->ts_mode, 0xff }, |
50 | { 0x02071, !priv->cfg.ts_clock_inv << 6, 0x40 }, | 51 | { 0x02071, !priv->ts_clk_inv << 6, 0x40 }, |
51 | { 0x020b5, priv->cfg.spec_inv << 4, 0x10 }, | 52 | { 0x020b5, priv->spec_inv << 4, 0x10 }, |
52 | { 0x02567, 0x07, 0x0f }, | 53 | { 0x02567, 0x07, 0x0f }, |
53 | { 0x02569, 0x03, 0x03 }, | 54 | { 0x02569, 0x03, 0x03 }, |
54 | { 0x02595, 0x1a, 0xff }, | 55 | { 0x02595, 0x1a, 0xff }, |
@@ -69,8 +70,10 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) | |||
69 | { 0x027ef, 0x10, 0x18 }, | 70 | { 0x027ef, 0x10, 0x18 }, |
70 | }; | 71 | }; |
71 | 72 | ||
72 | dev_dbg(&priv->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n", __func__, | 73 | dev_dbg(&client->dev, |
73 | c->frequency, c->bandwidth_hz); | 74 | "delivery_system=%d modulation=%d frequency=%u bandwidth_hz=%u inversion=%d stream_id=%u\n", |
75 | c->delivery_system, c->modulation, c->frequency, | ||
76 | c->bandwidth_hz, c->inversion, c->stream_id); | ||
74 | 77 | ||
75 | switch (c->bandwidth_hz) { | 78 | switch (c->bandwidth_hz) { |
76 | case 5000000: | 79 | case 5000000: |
@@ -98,73 +101,67 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe) | |||
98 | fe->ops.tuner_ops.set_params(fe); | 101 | fe->ops.tuner_ops.set_params(fe); |
99 | 102 | ||
100 | if (priv->delivery_system != SYS_DVBT2) { | 103 | if (priv->delivery_system != SYS_DVBT2) { |
101 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | 104 | ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); |
102 | ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, | 105 | if (ret) |
103 | tab[i].val, tab[i].mask); | 106 | goto error; |
104 | if (ret) | ||
105 | goto error; | ||
106 | } | ||
107 | } | 107 | } |
108 | 108 | ||
109 | priv->delivery_system = SYS_DVBT2; | 109 | priv->delivery_system = SYS_DVBT2; |
110 | 110 | ||
111 | /* program IF frequency */ | 111 | /* program IF frequency */ |
112 | if (fe->ops.tuner_ops.get_if_frequency) { | 112 | if (fe->ops.tuner_ops.get_if_frequency) { |
113 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq); | 113 | ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); |
114 | if (ret) | 114 | if (ret) |
115 | goto error; | 115 | goto error; |
116 | } else | 116 | dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency); |
117 | if_freq = 0; | 117 | } else { |
118 | 118 | ret = -EINVAL; | |
119 | dev_dbg(&priv->i2c->dev, "%s: if_freq=%d\n", __func__, if_freq); | 119 | goto error; |
120 | } | ||
120 | 121 | ||
121 | num = if_freq / 1000; /* Hz => kHz */ | 122 | utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, CXD2820R_CLK); |
122 | num *= 0x1000000; | 123 | buf[0] = (utmp >> 16) & 0xff; |
123 | if_ctl = DIV_ROUND_CLOSEST_ULL(num, 41000); | 124 | buf[1] = (utmp >> 8) & 0xff; |
124 | buf[0] = ((if_ctl >> 16) & 0xff); | 125 | buf[2] = (utmp >> 0) & 0xff; |
125 | buf[1] = ((if_ctl >> 8) & 0xff); | 126 | ret = regmap_bulk_write(priv->regmap[0], 0x20b6, buf, 3); |
126 | buf[2] = ((if_ctl >> 0) & 0xff); | 127 | if (ret) |
128 | goto error; | ||
127 | 129 | ||
128 | /* PLP filtering */ | 130 | /* PLP filtering */ |
129 | if (c->stream_id > 255) { | 131 | if (c->stream_id > 255) { |
130 | dev_dbg(&priv->i2c->dev, "%s: Disable PLP filtering\n", __func__); | 132 | dev_dbg(&client->dev, "disable PLP filtering\n"); |
131 | ret = cxd2820r_wr_reg(priv, 0x023ad , 0); | 133 | ret = regmap_write(priv->regmap[0], 0x23ad, 0x00); |
132 | if (ret) | 134 | if (ret) |
133 | goto error; | 135 | goto error; |
134 | } else { | 136 | } else { |
135 | dev_dbg(&priv->i2c->dev, "%s: Enable PLP filtering = %d\n", __func__, | 137 | dev_dbg(&client->dev, "enable PLP filtering\n"); |
136 | c->stream_id); | 138 | ret = regmap_write(priv->regmap[0], 0x23af, c->stream_id & 0xff); |
137 | ret = cxd2820r_wr_reg(priv, 0x023af , c->stream_id & 0xFF); | ||
138 | if (ret) | 139 | if (ret) |
139 | goto error; | 140 | goto error; |
140 | ret = cxd2820r_wr_reg(priv, 0x023ad , 1); | 141 | ret = regmap_write(priv->regmap[0], 0x23ad, 0x01); |
141 | if (ret) | 142 | if (ret) |
142 | goto error; | 143 | goto error; |
143 | } | 144 | } |
144 | 145 | ||
145 | ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3); | 146 | ret = regmap_bulk_write(priv->regmap[0], 0x209f, bw_params1[bw_i], 5); |
146 | if (ret) | 147 | if (ret) |
147 | goto error; | 148 | goto error; |
148 | 149 | ||
149 | ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[bw_i], 5); | 150 | ret = regmap_update_bits(priv->regmap[0], 0x20d7, 0xc0, bw_param << 6); |
150 | if (ret) | 151 | if (ret) |
151 | goto error; | 152 | goto error; |
152 | 153 | ||
153 | ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0); | 154 | ret = regmap_write(priv->regmap[0], 0x00ff, 0x08); |
154 | if (ret) | 155 | if (ret) |
155 | goto error; | 156 | goto error; |
156 | 157 | ||
157 | ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08); | 158 | ret = regmap_write(priv->regmap[0], 0x00fe, 0x01); |
158 | if (ret) | ||
159 | goto error; | ||
160 | |||
161 | ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01); | ||
162 | if (ret) | 159 | if (ret) |
163 | goto error; | 160 | goto error; |
164 | 161 | ||
165 | return ret; | 162 | return ret; |
166 | error: | 163 | error: |
167 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 164 | dev_dbg(&client->dev, "failed=%d\n", ret); |
168 | return ret; | 165 | return ret; |
169 | 166 | ||
170 | } | 167 | } |
@@ -173,10 +170,14 @@ int cxd2820r_get_frontend_t2(struct dvb_frontend *fe, | |||
173 | struct dtv_frontend_properties *c) | 170 | struct dtv_frontend_properties *c) |
174 | { | 171 | { |
175 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 172 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
173 | struct i2c_client *client = priv->client[0]; | ||
176 | int ret; | 174 | int ret; |
175 | unsigned int utmp; | ||
177 | u8 buf[2]; | 176 | u8 buf[2]; |
178 | 177 | ||
179 | ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2); | 178 | dev_dbg(&client->dev, "\n"); |
179 | |||
180 | ret = regmap_bulk_read(priv->regmap[0], 0x205c, buf, 2); | ||
180 | if (ret) | 181 | if (ret) |
181 | goto error; | 182 | goto error; |
182 | 183 | ||
@@ -225,7 +226,7 @@ int cxd2820r_get_frontend_t2(struct dvb_frontend *fe, | |||
225 | break; | 226 | break; |
226 | } | 227 | } |
227 | 228 | ||
228 | ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2); | 229 | ret = regmap_bulk_read(priv->regmap[0], 0x225b, buf, 2); |
229 | if (ret) | 230 | if (ret) |
230 | goto error; | 231 | goto error; |
231 | 232 | ||
@@ -265,11 +266,11 @@ int cxd2820r_get_frontend_t2(struct dvb_frontend *fe, | |||
265 | break; | 266 | break; |
266 | } | 267 | } |
267 | 268 | ||
268 | ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]); | 269 | ret = regmap_read(priv->regmap[0], 0x20b5, &utmp); |
269 | if (ret) | 270 | if (ret) |
270 | goto error; | 271 | goto error; |
271 | 272 | ||
272 | switch ((buf[0] >> 4) & 0x01) { | 273 | switch ((utmp >> 4) & 0x01) { |
273 | case 0: | 274 | case 0: |
274 | c->inversion = INVERSION_OFF; | 275 | c->inversion = INVERSION_OFF; |
275 | break; | 276 | break; |
@@ -280,130 +281,124 @@ int cxd2820r_get_frontend_t2(struct dvb_frontend *fe, | |||
280 | 281 | ||
281 | return ret; | 282 | return ret; |
282 | error: | 283 | error: |
283 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 284 | dev_dbg(&client->dev, "failed=%d\n", ret); |
284 | return ret; | 285 | return ret; |
285 | } | 286 | } |
286 | 287 | ||
287 | int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status) | 288 | int cxd2820r_read_status_t2(struct dvb_frontend *fe, enum fe_status *status) |
288 | { | 289 | { |
289 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 290 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
291 | struct dtv_frontend_properties *c = &fe->dtv_property_cache; | ||
292 | struct i2c_client *client = priv->client[0]; | ||
290 | int ret; | 293 | int ret; |
291 | u8 buf[1]; | 294 | unsigned int utmp, utmp1, utmp2; |
292 | *status = 0; | 295 | u8 buf[4]; |
293 | 296 | ||
294 | ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]); | 297 | /* Lock detection */ |
298 | ret = regmap_bulk_read(priv->regmap[0], 0x2010, &buf[0], 1); | ||
295 | if (ret) | 299 | if (ret) |
296 | goto error; | 300 | goto error; |
297 | 301 | ||
298 | if ((buf[0] & 0x07) == 6) { | 302 | utmp1 = (buf[0] >> 0) & 0x07; |
299 | if (((buf[0] >> 5) & 0x01) == 1) { | 303 | utmp2 = (buf[0] >> 5) & 0x01; |
300 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
301 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
302 | } else { | ||
303 | *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
304 | FE_HAS_VITERBI | FE_HAS_SYNC; | ||
305 | } | ||
306 | } | ||
307 | 304 | ||
308 | dev_dbg(&priv->i2c->dev, "%s: lock=%02x\n", __func__, buf[0]); | 305 | if (utmp1 == 6 && utmp2 == 1) { |
306 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
307 | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
308 | } else if (utmp1 == 6 || utmp2 == 1) { | ||
309 | *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | | ||
310 | FE_HAS_VITERBI | FE_HAS_SYNC; | ||
311 | } else { | ||
312 | *status = 0; | ||
313 | } | ||
309 | 314 | ||
310 | return ret; | 315 | dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n", |
311 | error: | 316 | *status, 1, buf, utmp1, utmp2); |
312 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | ||
313 | return ret; | ||
314 | } | ||
315 | 317 | ||
316 | int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber) | 318 | /* Signal strength */ |
317 | { | 319 | if (*status & FE_HAS_SIGNAL) { |
318 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 320 | unsigned int strength; |
319 | int ret; | ||
320 | u8 buf[4]; | ||
321 | unsigned int errbits; | ||
322 | *ber = 0; | ||
323 | /* FIXME: correct calculation */ | ||
324 | 321 | ||
325 | ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf)); | 322 | ret = regmap_bulk_read(priv->regmap[0], 0x2026, buf, 2); |
326 | if (ret) | 323 | if (ret) |
327 | goto error; | 324 | goto error; |
328 | 325 | ||
329 | if ((buf[0] >> 4) & 0x01) { | 326 | utmp = buf[0] << 8 | buf[1] << 0; |
330 | errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 | | 327 | utmp = ~utmp & 0x0fff; |
331 | buf[2] << 8 | buf[3]; | 328 | /* Scale value to 0x0000-0xffff */ |
329 | strength = utmp << 4 | utmp >> 8; | ||
332 | 330 | ||
333 | if (errbits) | 331 | c->strength.len = 1; |
334 | *ber = errbits * 64 / 16588800; | 332 | c->strength.stat[0].scale = FE_SCALE_RELATIVE; |
333 | c->strength.stat[0].uvalue = strength; | ||
334 | } else { | ||
335 | c->strength.len = 1; | ||
336 | c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
335 | } | 337 | } |
336 | 338 | ||
337 | return ret; | 339 | /* CNR */ |
338 | error: | 340 | if (*status & FE_HAS_VITERBI) { |
339 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 341 | unsigned int cnr; |
340 | return ret; | ||
341 | } | ||
342 | 342 | ||
343 | int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, | 343 | ret = regmap_bulk_read(priv->regmap[0], 0x2028, buf, 2); |
344 | u16 *strength) | 344 | if (ret) |
345 | { | 345 | goto error; |
346 | struct cxd2820r_priv *priv = fe->demodulator_priv; | ||
347 | int ret; | ||
348 | u8 buf[2]; | ||
349 | u16 tmp; | ||
350 | |||
351 | ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf)); | ||
352 | if (ret) | ||
353 | goto error; | ||
354 | |||
355 | tmp = (buf[0] & 0x0f) << 8 | buf[1]; | ||
356 | tmp = ~tmp & 0x0fff; | ||
357 | 346 | ||
358 | /* scale value to 0x0000-0xffff from 0x0000-0x0fff */ | 347 | utmp = buf[0] << 8 | buf[1] << 0; |
359 | *strength = tmp * 0xffff / 0x0fff; | 348 | utmp = utmp & 0x0fff; |
349 | #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */ | ||
350 | if (utmp) | ||
351 | cnr = div_u64((u64)(intlog10(utmp) | ||
352 | - CXD2820R_LOG10_8_24) * 10000, | ||
353 | (1 << 24)); | ||
354 | else | ||
355 | cnr = 0; | ||
356 | |||
357 | c->cnr.len = 1; | ||
358 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | ||
359 | c->cnr.stat[0].svalue = cnr; | ||
360 | } else { | ||
361 | c->cnr.len = 1; | ||
362 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
363 | } | ||
360 | 364 | ||
361 | return ret; | 365 | /* BER */ |
362 | error: | 366 | if (*status & FE_HAS_SYNC) { |
363 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 367 | unsigned int post_bit_error; |
364 | return ret; | ||
365 | } | ||
366 | 368 | ||
367 | int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr) | 369 | ret = regmap_bulk_read(priv->regmap[0], 0x2039, buf, 4); |
368 | { | 370 | if (ret) |
369 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 371 | goto error; |
370 | int ret; | ||
371 | u8 buf[2]; | ||
372 | u16 tmp; | ||
373 | /* report SNR in dB * 10 */ | ||
374 | 372 | ||
375 | ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf)); | 373 | if ((buf[0] >> 4) & 0x01) { |
376 | if (ret) | 374 | post_bit_error = buf[0] << 24 | buf[1] << 16 | |
377 | goto error; | 375 | buf[2] << 8 | buf[3] << 0; |
376 | post_bit_error &= 0x0fffffff; | ||
377 | } else { | ||
378 | post_bit_error = 0; | ||
379 | } | ||
378 | 380 | ||
379 | tmp = (buf[0] & 0x0f) << 8 | buf[1]; | 381 | priv->post_bit_error += post_bit_error; |
380 | #define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */ | ||
381 | if (tmp) | ||
382 | *snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24) | ||
383 | / 100); | ||
384 | else | ||
385 | *snr = 0; | ||
386 | 382 | ||
387 | dev_dbg(&priv->i2c->dev, "%s: dBx10=%d val=%04x\n", __func__, *snr, | 383 | c->post_bit_error.len = 1; |
388 | tmp); | 384 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; |
385 | c->post_bit_error.stat[0].uvalue = priv->post_bit_error; | ||
386 | } else { | ||
387 | c->post_bit_error.len = 1; | ||
388 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
389 | } | ||
389 | 390 | ||
390 | return ret; | 391 | return ret; |
391 | error: | 392 | error: |
392 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 393 | dev_dbg(&client->dev, "failed=%d\n", ret); |
393 | return ret; | 394 | return ret; |
394 | } | 395 | } |
395 | 396 | ||
396 | int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks) | ||
397 | { | ||
398 | *ucblocks = 0; | ||
399 | /* no way to read ? */ | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | int cxd2820r_sleep_t2(struct dvb_frontend *fe) | 397 | int cxd2820r_sleep_t2(struct dvb_frontend *fe) |
404 | { | 398 | { |
405 | struct cxd2820r_priv *priv = fe->demodulator_priv; | 399 | struct cxd2820r_priv *priv = fe->demodulator_priv; |
406 | int ret, i; | 400 | struct i2c_client *client = priv->client[0]; |
401 | int ret; | ||
407 | struct reg_val_mask tab[] = { | 402 | struct reg_val_mask tab[] = { |
408 | { 0x000ff, 0x1f, 0xff }, | 403 | { 0x000ff, 0x1f, 0xff }, |
409 | { 0x00085, 0x00, 0xff }, | 404 | { 0x00085, 0x00, 0xff }, |
@@ -413,20 +408,17 @@ int cxd2820r_sleep_t2(struct dvb_frontend *fe) | |||
413 | { 0x00080, 0x00, 0xff }, | 408 | { 0x00080, 0x00, 0xff }, |
414 | }; | 409 | }; |
415 | 410 | ||
416 | dev_dbg(&priv->i2c->dev, "%s\n", __func__); | 411 | dev_dbg(&client->dev, "\n"); |
417 | 412 | ||
418 | for (i = 0; i < ARRAY_SIZE(tab); i++) { | 413 | ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab)); |
419 | ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val, | 414 | if (ret) |
420 | tab[i].mask); | 415 | goto error; |
421 | if (ret) | ||
422 | goto error; | ||
423 | } | ||
424 | 416 | ||
425 | priv->delivery_system = SYS_UNDEFINED; | 417 | priv->delivery_system = SYS_UNDEFINED; |
426 | 418 | ||
427 | return ret; | 419 | return ret; |
428 | error: | 420 | error: |
429 | dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); | 421 | dev_dbg(&client->dev, "failed=%d\n", ret); |
430 | return ret; | 422 | return ret; |
431 | } | 423 | } |
432 | 424 | ||
diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index ffe88bc6b813..5afb9c508f65 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c | |||
@@ -206,6 +206,9 @@ static const struct cxd2841er_cnr_data s2_cn_data[] = { | |||
206 | (u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \ | 206 | (u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \ |
207 | (u32)(((iffreq)/41.0)*16777216.0 + 0.5)) | 207 | (u32)(((iffreq)/41.0)*16777216.0 + 0.5)) |
208 | 208 | ||
209 | static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv); | ||
210 | static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv); | ||
211 | |||
209 | static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv, | 212 | static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv, |
210 | u8 addr, u8 reg, u8 write, | 213 | u8 addr, u8 reg, u8 write, |
211 | const u8 *data, u32 len) | 214 | const u8 *data, u32 len) |
@@ -1401,6 +1404,41 @@ static int cxd2841er_read_ber_c(struct cxd2841er_priv *priv, | |||
1401 | return 0; | 1404 | return 0; |
1402 | } | 1405 | } |
1403 | 1406 | ||
1407 | static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv, | ||
1408 | u32 *bit_error, u32 *bit_count) | ||
1409 | { | ||
1410 | u8 data[3]; | ||
1411 | u8 pktnum[2]; | ||
1412 | |||
1413 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | ||
1414 | if (priv->state != STATE_ACTIVE_TC) { | ||
1415 | dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", | ||
1416 | __func__, priv->state); | ||
1417 | return -EINVAL; | ||
1418 | } | ||
1419 | |||
1420 | cxd2841er_freeze_regs(priv); | ||
1421 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); | ||
1422 | cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum)); | ||
1423 | cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data)); | ||
1424 | |||
1425 | if (!pktnum[0] && !pktnum[1]) { | ||
1426 | dev_dbg(&priv->i2c->dev, | ||
1427 | "%s(): no valid BER data\n", __func__); | ||
1428 | cxd2841er_unfreeze_regs(priv); | ||
1429 | return -EINVAL; | ||
1430 | } | ||
1431 | |||
1432 | *bit_error = ((u32)(data[0] & 0x7F) << 16) | | ||
1433 | ((u32)data[1] << 8) | data[2]; | ||
1434 | *bit_count = ((((u32)pktnum[0] << 8) | pktnum[1]) * 204 * 8); | ||
1435 | dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n", | ||
1436 | __func__, *bit_error, *bit_count); | ||
1437 | |||
1438 | cxd2841er_unfreeze_regs(priv); | ||
1439 | return 0; | ||
1440 | } | ||
1441 | |||
1404 | static int cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv, | 1442 | static int cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv, |
1405 | u32 *bit_error, u32 *bit_count) | 1443 | u32 *bit_error, u32 *bit_count) |
1406 | { | 1444 | { |
@@ -1570,6 +1608,25 @@ static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv, | |||
1570 | return 0; | 1608 | return 0; |
1571 | } | 1609 | } |
1572 | 1610 | ||
1611 | static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv) | ||
1612 | { | ||
1613 | /* | ||
1614 | * Freeze registers: ensure multiple separate register reads | ||
1615 | * are from the same snapshot | ||
1616 | */ | ||
1617 | cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01); | ||
1618 | return 0; | ||
1619 | } | ||
1620 | |||
1621 | static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv) | ||
1622 | { | ||
1623 | /* | ||
1624 | * un-freeze registers | ||
1625 | */ | ||
1626 | cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x00); | ||
1627 | return 0; | ||
1628 | } | ||
1629 | |||
1573 | static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, | 1630 | static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, |
1574 | u8 delsys, u32 *snr) | 1631 | u8 delsys, u32 *snr) |
1575 | { | 1632 | { |
@@ -1578,6 +1635,7 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, | |||
1578 | int min_index, max_index, index; | 1635 | int min_index, max_index, index; |
1579 | static const struct cxd2841er_cnr_data *cn_data; | 1636 | static const struct cxd2841er_cnr_data *cn_data; |
1580 | 1637 | ||
1638 | cxd2841er_freeze_regs(priv); | ||
1581 | /* Set SLV-T Bank : 0xA1 */ | 1639 | /* Set SLV-T Bank : 0xA1 */ |
1582 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1); | 1640 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1); |
1583 | /* | 1641 | /* |
@@ -1629,9 +1687,11 @@ static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, | |||
1629 | } else { | 1687 | } else { |
1630 | dev_dbg(&priv->i2c->dev, | 1688 | dev_dbg(&priv->i2c->dev, |
1631 | "%s(): no data available\n", __func__); | 1689 | "%s(): no data available\n", __func__); |
1690 | cxd2841er_unfreeze_regs(priv); | ||
1632 | return -EINVAL; | 1691 | return -EINVAL; |
1633 | } | 1692 | } |
1634 | done: | 1693 | done: |
1694 | cxd2841er_unfreeze_regs(priv); | ||
1635 | *snr = res; | 1695 | *snr = res; |
1636 | return 0; | 1696 | return 0; |
1637 | } | 1697 | } |
@@ -1655,12 +1715,7 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) | |||
1655 | return -EINVAL; | 1715 | return -EINVAL; |
1656 | } | 1716 | } |
1657 | 1717 | ||
1658 | /* | 1718 | cxd2841er_freeze_regs(priv); |
1659 | * Freeze registers: ensure multiple separate register reads | ||
1660 | * are from the same snapshot | ||
1661 | */ | ||
1662 | cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01); | ||
1663 | |||
1664 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); | 1719 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); |
1665 | cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1); | 1720 | cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1); |
1666 | qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07); | 1721 | qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07); |
@@ -1670,6 +1725,7 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) | |||
1670 | if (reg == 0) { | 1725 | if (reg == 0) { |
1671 | dev_dbg(&priv->i2c->dev, | 1726 | dev_dbg(&priv->i2c->dev, |
1672 | "%s(): reg value out of range\n", __func__); | 1727 | "%s(): reg value out of range\n", __func__); |
1728 | cxd2841er_unfreeze_regs(priv); | ||
1673 | return 0; | 1729 | return 0; |
1674 | } | 1730 | } |
1675 | 1731 | ||
@@ -1690,9 +1746,11 @@ static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) | |||
1690 | *snr = -88 * (int32_t)sony_log(reg) + 86999; | 1746 | *snr = -88 * (int32_t)sony_log(reg) + 86999; |
1691 | break; | 1747 | break; |
1692 | default: | 1748 | default: |
1749 | cxd2841er_unfreeze_regs(priv); | ||
1693 | return -EINVAL; | 1750 | return -EINVAL; |
1694 | } | 1751 | } |
1695 | 1752 | ||
1753 | cxd2841er_unfreeze_regs(priv); | ||
1696 | return 0; | 1754 | return 0; |
1697 | } | 1755 | } |
1698 | 1756 | ||
@@ -1707,17 +1765,21 @@ static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr) | |||
1707 | "%s(): invalid state %d\n", __func__, priv->state); | 1765 | "%s(): invalid state %d\n", __func__, priv->state); |
1708 | return -EINVAL; | 1766 | return -EINVAL; |
1709 | } | 1767 | } |
1768 | |||
1769 | cxd2841er_freeze_regs(priv); | ||
1710 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); | 1770 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); |
1711 | cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); | 1771 | cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); |
1712 | reg = ((u32)data[0] << 8) | (u32)data[1]; | 1772 | reg = ((u32)data[0] << 8) | (u32)data[1]; |
1713 | if (reg == 0) { | 1773 | if (reg == 0) { |
1714 | dev_dbg(&priv->i2c->dev, | 1774 | dev_dbg(&priv->i2c->dev, |
1715 | "%s(): reg value out of range\n", __func__); | 1775 | "%s(): reg value out of range\n", __func__); |
1776 | cxd2841er_unfreeze_regs(priv); | ||
1716 | return 0; | 1777 | return 0; |
1717 | } | 1778 | } |
1718 | if (reg > 4996) | 1779 | if (reg > 4996) |
1719 | reg = 4996; | 1780 | reg = 4996; |
1720 | *snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500; | 1781 | *snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500; |
1782 | cxd2841er_unfreeze_regs(priv); | ||
1721 | return 0; | 1783 | return 0; |
1722 | } | 1784 | } |
1723 | 1785 | ||
@@ -1732,18 +1794,22 @@ static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr) | |||
1732 | "%s(): invalid state %d\n", __func__, priv->state); | 1794 | "%s(): invalid state %d\n", __func__, priv->state); |
1733 | return -EINVAL; | 1795 | return -EINVAL; |
1734 | } | 1796 | } |
1797 | |||
1798 | cxd2841er_freeze_regs(priv); | ||
1735 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); | 1799 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); |
1736 | cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); | 1800 | cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); |
1737 | reg = ((u32)data[0] << 8) | (u32)data[1]; | 1801 | reg = ((u32)data[0] << 8) | (u32)data[1]; |
1738 | if (reg == 0) { | 1802 | if (reg == 0) { |
1739 | dev_dbg(&priv->i2c->dev, | 1803 | dev_dbg(&priv->i2c->dev, |
1740 | "%s(): reg value out of range\n", __func__); | 1804 | "%s(): reg value out of range\n", __func__); |
1805 | cxd2841er_unfreeze_regs(priv); | ||
1741 | return 0; | 1806 | return 0; |
1742 | } | 1807 | } |
1743 | if (reg > 10876) | 1808 | if (reg > 10876) |
1744 | reg = 10876; | 1809 | reg = 10876; |
1745 | *snr = 10000 * ((intlog10(reg) - | 1810 | *snr = 10000 * ((intlog10(reg) - |
1746 | intlog10(12600 - reg)) >> 24) + 32000; | 1811 | intlog10(12600 - reg)) >> 24) + 32000; |
1812 | cxd2841er_unfreeze_regs(priv); | ||
1747 | return 0; | 1813 | return 0; |
1748 | } | 1814 | } |
1749 | 1815 | ||
@@ -1760,21 +1826,18 @@ static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr) | |||
1760 | return -EINVAL; | 1826 | return -EINVAL; |
1761 | } | 1827 | } |
1762 | 1828 | ||
1763 | /* Freeze all registers */ | 1829 | cxd2841er_freeze_regs(priv); |
1764 | cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01); | ||
1765 | |||
1766 | |||
1767 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); | 1830 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); |
1768 | cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); | 1831 | cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); |
1769 | reg = ((u32)data[0] << 8) | (u32)data[1]; | 1832 | reg = ((u32)data[0] << 8) | (u32)data[1]; |
1770 | if (reg == 0) { | 1833 | if (reg == 0) { |
1771 | dev_dbg(&priv->i2c->dev, | 1834 | dev_dbg(&priv->i2c->dev, |
1772 | "%s(): reg value out of range\n", __func__); | 1835 | "%s(): reg value out of range\n", __func__); |
1836 | cxd2841er_unfreeze_regs(priv); | ||
1773 | return 0; | 1837 | return 0; |
1774 | } | 1838 | } |
1775 | if (reg > 4996) | 1839 | *snr = 10000 * (intlog10(reg) >> 24) - 9031; |
1776 | reg = 4996; | 1840 | cxd2841er_unfreeze_regs(priv); |
1777 | *snr = 100 * intlog10(reg) - 9031; | ||
1778 | return 0; | 1841 | return 0; |
1779 | } | 1842 | } |
1780 | 1843 | ||
@@ -1852,6 +1915,9 @@ static void cxd2841er_read_ber(struct dvb_frontend *fe) | |||
1852 | case SYS_DVBC_ANNEX_C: | 1915 | case SYS_DVBC_ANNEX_C: |
1853 | ret = cxd2841er_read_ber_c(priv, &bit_error, &bit_count); | 1916 | ret = cxd2841er_read_ber_c(priv, &bit_error, &bit_count); |
1854 | break; | 1917 | break; |
1918 | case SYS_ISDBT: | ||
1919 | ret = cxd2841er_read_ber_i(priv, &bit_error, &bit_count); | ||
1920 | break; | ||
1855 | case SYS_DVBS: | 1921 | case SYS_DVBS: |
1856 | ret = cxd2841er_mon_read_ber_s(priv, &bit_error, &bit_count); | 1922 | ret = cxd2841er_mon_read_ber_s(priv, &bit_error, &bit_count); |
1857 | break; | 1923 | break; |
@@ -1965,6 +2031,9 @@ static void cxd2841er_read_snr(struct dvb_frontend *fe) | |||
1965 | return; | 2031 | return; |
1966 | } | 2032 | } |
1967 | 2033 | ||
2034 | dev_dbg(&priv->i2c->dev, "%s(): snr=%d\n", | ||
2035 | __func__, (int32_t)tmp); | ||
2036 | |||
1968 | if (!ret) { | 2037 | if (!ret) { |
1969 | p->cnr.stat[0].scale = FE_SCALE_DECIBEL; | 2038 | p->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
1970 | p->cnr.stat[0].svalue = tmp; | 2039 | p->cnr.stat[0].svalue = tmp; |
@@ -1977,7 +2046,7 @@ static void cxd2841er_read_ucblocks(struct dvb_frontend *fe) | |||
1977 | { | 2046 | { |
1978 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | 2047 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; |
1979 | struct cxd2841er_priv *priv = fe->demodulator_priv; | 2048 | struct cxd2841er_priv *priv = fe->demodulator_priv; |
1980 | u32 ucblocks; | 2049 | u32 ucblocks = 0; |
1981 | 2050 | ||
1982 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | 2051 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); |
1983 | switch (p->delivery_system) { | 2052 | switch (p->delivery_system) { |
@@ -1999,7 +2068,7 @@ static void cxd2841er_read_ucblocks(struct dvb_frontend *fe) | |||
1999 | p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 2068 | p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
2000 | return; | 2069 | return; |
2001 | } | 2070 | } |
2002 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | 2071 | dev_dbg(&priv->i2c->dev, "%s() ucblocks=%u\n", __func__, ucblocks); |
2003 | 2072 | ||
2004 | p->block_error.stat[0].scale = FE_SCALE_COUNTER; | 2073 | p->block_error.stat[0].scale = FE_SCALE_COUNTER; |
2005 | p->block_error.stat[0].uvalue = ucblocks; | 2074 | p->block_error.stat[0].uvalue = ucblocks; |
@@ -2694,6 +2763,14 @@ static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv, | |||
2694 | u8 b10_b6[3]; | 2763 | u8 b10_b6[3]; |
2695 | u32 iffreq; | 2764 | u32 iffreq; |
2696 | 2765 | ||
2766 | if (bandwidth != 6000000 && | ||
2767 | bandwidth != 7000000 && | ||
2768 | bandwidth != 8000000) { | ||
2769 | dev_info(&priv->i2c->dev, "%s(): unsupported bandwidth %d. Forcing 8Mhz!\n", | ||
2770 | __func__, bandwidth); | ||
2771 | bandwidth = 8000000; | ||
2772 | } | ||
2773 | |||
2697 | dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth); | 2774 | dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth); |
2698 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); | 2775 | cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); |
2699 | switch (bandwidth) { | 2776 | switch (bandwidth) { |
@@ -3076,6 +3153,7 @@ static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv, | |||
3076 | /* Enable demod clock */ | 3153 | /* Enable demod clock */ |
3077 | cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); | 3154 | cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); |
3078 | /* Disable RF level monitor */ | 3155 | /* Disable RF level monitor */ |
3156 | cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00); | ||
3079 | cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); | 3157 | cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); |
3080 | /* Enable ADC clock */ | 3158 | /* Enable ADC clock */ |
3081 | cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); | 3159 | cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); |
diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index b975da099929..c595adc61c6f 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c | |||
@@ -6448,7 +6448,7 @@ static int get_strength(struct drxk_state *state, u64 *strength) | |||
6448 | return status; | 6448 | return status; |
6449 | 6449 | ||
6450 | /* SCU c.o.c. */ | 6450 | /* SCU c.o.c. */ |
6451 | read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); | 6451 | status = read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc); |
6452 | if (status < 0) | 6452 | if (status < 0) |
6453 | return status; | 6453 | return status; |
6454 | 6454 | ||
diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index 53089e142715..735a96662022 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c | |||
@@ -739,7 +739,7 @@ static int dvb_pll_init(struct dvb_frontend *fe) | |||
739 | return -EINVAL; | 739 | return -EINVAL; |
740 | } | 740 | } |
741 | 741 | ||
742 | static struct dvb_tuner_ops dvb_pll_tuner_ops = { | 742 | static const struct dvb_tuner_ops dvb_pll_tuner_ops = { |
743 | .release = dvb_pll_release, | 743 | .release = dvb_pll_release, |
744 | .sleep = dvb_pll_sleep, | 744 | .sleep = dvb_pll_sleep, |
745 | .init = dvb_pll_init, | 745 | .init = dvb_pll_init, |
diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c index 97a8982740a6..dc43c5f6d0ea 100644 --- a/drivers/media/dvb-frontends/helene.c +++ b/drivers/media/dvb-frontends/helene.c | |||
@@ -842,7 +842,7 @@ static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
842 | return 0; | 842 | return 0; |
843 | } | 843 | } |
844 | 844 | ||
845 | static struct dvb_tuner_ops helene_tuner_ops = { | 845 | static const struct dvb_tuner_ops helene_tuner_ops = { |
846 | .info = { | 846 | .info = { |
847 | .name = "Sony HELENE Ter tuner", | 847 | .name = "Sony HELENE Ter tuner", |
848 | .frequency_min = 1000000, | 848 | .frequency_min = 1000000, |
@@ -856,7 +856,7 @@ static struct dvb_tuner_ops helene_tuner_ops = { | |||
856 | .get_frequency = helene_get_frequency, | 856 | .get_frequency = helene_get_frequency, |
857 | }; | 857 | }; |
858 | 858 | ||
859 | static struct dvb_tuner_ops helene_tuner_ops_s = { | 859 | static const struct dvb_tuner_ops helene_tuner_ops_s = { |
860 | .info = { | 860 | .info = { |
861 | .name = "Sony HELENE Sat tuner", | 861 | .name = "Sony HELENE Sat tuner", |
862 | .frequency_min = 500000, | 862 | .frequency_min = 500000, |
@@ -987,8 +987,10 @@ struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe, | |||
987 | if (fe->ops.i2c_gate_ctrl) | 987 | if (fe->ops.i2c_gate_ctrl) |
988 | fe->ops.i2c_gate_ctrl(fe, 1); | 988 | fe->ops.i2c_gate_ctrl(fe, 1); |
989 | 989 | ||
990 | if (helene_x_pon(priv) != 0) | 990 | if (helene_x_pon(priv) != 0) { |
991 | kfree(priv); | ||
991 | return NULL; | 992 | return NULL; |
993 | } | ||
992 | 994 | ||
993 | if (fe->ops.i2c_gate_ctrl) | 995 | if (fe->ops.i2c_gate_ctrl) |
994 | fe->ops.i2c_gate_ctrl(fe, 0); | 996 | fe->ops.i2c_gate_ctrl(fe, 0); |
@@ -1021,8 +1023,10 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe, | |||
1021 | if (fe->ops.i2c_gate_ctrl) | 1023 | if (fe->ops.i2c_gate_ctrl) |
1022 | fe->ops.i2c_gate_ctrl(fe, 1); | 1024 | fe->ops.i2c_gate_ctrl(fe, 1); |
1023 | 1025 | ||
1024 | if (helene_x_pon(priv) != 0) | 1026 | if (helene_x_pon(priv) != 0) { |
1027 | kfree(priv); | ||
1025 | return NULL; | 1028 | return NULL; |
1029 | } | ||
1026 | 1030 | ||
1027 | if (fe->ops.i2c_gate_ctrl) | 1031 | if (fe->ops.i2c_gate_ctrl) |
1028 | fe->ops.i2c_gate_ctrl(fe, 0); | 1032 | fe->ops.i2c_gate_ctrl(fe, 0); |
diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c index a98bca5270d9..0c089b5986a1 100644 --- a/drivers/media/dvb-frontends/horus3a.c +++ b/drivers/media/dvb-frontends/horus3a.c | |||
@@ -326,7 +326,7 @@ static int horus3a_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
326 | return 0; | 326 | return 0; |
327 | } | 327 | } |
328 | 328 | ||
329 | static struct dvb_tuner_ops horus3a_tuner_ops = { | 329 | static const struct dvb_tuner_ops horus3a_tuner_ops = { |
330 | .info = { | 330 | .info = { |
331 | .name = "Sony Horus3a", | 331 | .name = "Sony Horus3a", |
332 | .frequency_min = 950000, | 332 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c index 0e3387e00952..2826bbb36b73 100644 --- a/drivers/media/dvb-frontends/ix2505v.c +++ b/drivers/media/dvb-frontends/ix2505v.c | |||
@@ -258,7 +258,7 @@ static int ix2505v_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
258 | return 0; | 258 | return 0; |
259 | } | 259 | } |
260 | 260 | ||
261 | static struct dvb_tuner_ops ix2505v_tuner_ops = { | 261 | static const struct dvb_tuner_ops ix2505v_tuner_ops = { |
262 | .info = { | 262 | .info = { |
263 | .name = "Sharp IX2505V (B0017)", | 263 | .name = "Sharp IX2505V (B0017)", |
264 | .frequency_min = 950000, | 264 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 179c26e5eb4e..0ca4e810e9d8 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c | |||
@@ -731,7 +731,7 @@ static int lgdt3306a_set_if(struct lgdt3306a_state *state, | |||
731 | 731 | ||
732 | switch (if_freq_khz) { | 732 | switch (if_freq_khz) { |
733 | default: | 733 | default: |
734 | pr_warn("IF=%d KHz is not supportted, 3250 assumed\n", | 734 | pr_warn("IF=%d KHz is not supported, 3250 assumed\n", |
735 | if_freq_khz); | 735 | if_freq_khz); |
736 | /* fallthrough */ | 736 | /* fallthrough */ |
737 | case 3250: /* 3.25Mhz */ | 737 | case 3250: /* 3.25Mhz */ |
@@ -1737,24 +1737,16 @@ static int lgdt3306a_get_tune_settings(struct dvb_frontend *fe, | |||
1737 | static int lgdt3306a_search(struct dvb_frontend *fe) | 1737 | static int lgdt3306a_search(struct dvb_frontend *fe) |
1738 | { | 1738 | { |
1739 | enum fe_status status = 0; | 1739 | enum fe_status status = 0; |
1740 | int i, ret; | 1740 | int ret; |
1741 | 1741 | ||
1742 | /* set frontend */ | 1742 | /* set frontend */ |
1743 | ret = lgdt3306a_set_parameters(fe); | 1743 | ret = lgdt3306a_set_parameters(fe); |
1744 | if (ret) | 1744 | if (ret) |
1745 | goto error; | 1745 | goto error; |
1746 | 1746 | ||
1747 | /* wait frontend lock */ | 1747 | ret = lgdt3306a_read_status(fe, &status); |
1748 | for (i = 20; i > 0; i--) { | 1748 | if (ret) |
1749 | dbg_info(": loop=%d\n", i); | 1749 | goto error; |
1750 | msleep(50); | ||
1751 | ret = lgdt3306a_read_status(fe, &status); | ||
1752 | if (ret) | ||
1753 | goto error; | ||
1754 | |||
1755 | if (status & FE_HAS_LOCK) | ||
1756 | break; | ||
1757 | } | ||
1758 | 1750 | ||
1759 | /* check if we have a valid signal */ | 1751 | /* check if we have a valid signal */ |
1760 | if (status & FE_HAS_LOCK) | 1752 | if (status & FE_HAS_LOCK) |
diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 41325328a22e..fe79358b035e 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c | |||
@@ -71,25 +71,27 @@ static struct regdata mb86a20s_init1[] = { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | static struct regdata mb86a20s_init2[] = { | 73 | static struct regdata mb86a20s_init2[] = { |
74 | { 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 }, | 74 | { 0x50, 0xd1 }, { 0x51, 0x22 }, |
75 | { 0x39, 0x01 }, | ||
76 | { 0x71, 0x00 }, | ||
75 | { 0x3b, 0x21 }, | 77 | { 0x3b, 0x21 }, |
76 | { 0x3c, 0x38 }, | 78 | { 0x3c, 0x3a }, |
77 | { 0x01, 0x0d }, | 79 | { 0x01, 0x0d }, |
78 | { 0x04, 0x08 }, { 0x05, 0x03 }, | 80 | { 0x04, 0x08 }, { 0x05, 0x05 }, |
79 | { 0x04, 0x0e }, { 0x05, 0x00 }, | 81 | { 0x04, 0x0e }, { 0x05, 0x00 }, |
80 | { 0x04, 0x0f }, { 0x05, 0x37 }, | 82 | { 0x04, 0x0f }, { 0x05, 0x14 }, |
81 | { 0x04, 0x0b }, { 0x05, 0x78 }, | 83 | { 0x04, 0x0b }, { 0x05, 0x8c }, |
82 | { 0x04, 0x00 }, { 0x05, 0x00 }, | 84 | { 0x04, 0x00 }, { 0x05, 0x00 }, |
83 | { 0x04, 0x01 }, { 0x05, 0x1e }, | 85 | { 0x04, 0x01 }, { 0x05, 0x07 }, |
84 | { 0x04, 0x02 }, { 0x05, 0x07 }, | 86 | { 0x04, 0x02 }, { 0x05, 0x0f }, |
85 | { 0x04, 0x03 }, { 0x05, 0xd0 }, | 87 | { 0x04, 0x03 }, { 0x05, 0xa0 }, |
86 | { 0x04, 0x09 }, { 0x05, 0x00 }, | 88 | { 0x04, 0x09 }, { 0x05, 0x00 }, |
87 | { 0x04, 0x0a }, { 0x05, 0xff }, | 89 | { 0x04, 0x0a }, { 0x05, 0xff }, |
88 | { 0x04, 0x27 }, { 0x05, 0x00 }, | 90 | { 0x04, 0x27 }, { 0x05, 0x64 }, |
89 | { 0x04, 0x28 }, { 0x05, 0x00 }, | 91 | { 0x04, 0x28 }, { 0x05, 0x00 }, |
90 | { 0x04, 0x1e }, { 0x05, 0x00 }, | 92 | { 0x04, 0x1e }, { 0x05, 0xff }, |
91 | { 0x04, 0x29 }, { 0x05, 0x64 }, | 93 | { 0x04, 0x29 }, { 0x05, 0x0a }, |
92 | { 0x04, 0x32 }, { 0x05, 0x02 }, | 94 | { 0x04, 0x32 }, { 0x05, 0x0a }, |
93 | { 0x04, 0x14 }, { 0x05, 0x02 }, | 95 | { 0x04, 0x14 }, { 0x05, 0x02 }, |
94 | { 0x04, 0x04 }, { 0x05, 0x00 }, | 96 | { 0x04, 0x04 }, { 0x05, 0x00 }, |
95 | { 0x04, 0x05 }, { 0x05, 0x22 }, | 97 | { 0x04, 0x05 }, { 0x05, 0x22 }, |
@@ -97,8 +99,6 @@ static struct regdata mb86a20s_init2[] = { | |||
97 | { 0x04, 0x07 }, { 0x05, 0xd8 }, | 99 | { 0x04, 0x07 }, { 0x05, 0xd8 }, |
98 | { 0x04, 0x12 }, { 0x05, 0x00 }, | 100 | { 0x04, 0x12 }, { 0x05, 0x00 }, |
99 | { 0x04, 0x13 }, { 0x05, 0xff }, | 101 | { 0x04, 0x13 }, { 0x05, 0xff }, |
100 | { 0x04, 0x15 }, { 0x05, 0x4e }, | ||
101 | { 0x04, 0x16 }, { 0x05, 0x20 }, | ||
102 | 102 | ||
103 | /* | 103 | /* |
104 | * On this demod, when the bit count reaches the count below, | 104 | * On this demod, when the bit count reaches the count below, |
@@ -152,42 +152,36 @@ static struct regdata mb86a20s_init2[] = { | |||
152 | { 0x50, 0x51 }, { 0x51, 0x04 }, /* MER symbol 4 */ | 152 | { 0x50, 0x51 }, { 0x51, 0x04 }, /* MER symbol 4 */ |
153 | { 0x45, 0x04 }, /* CN symbol 4 */ | 153 | { 0x45, 0x04 }, /* CN symbol 4 */ |
154 | { 0x48, 0x04 }, /* CN manual mode */ | 154 | { 0x48, 0x04 }, /* CN manual mode */ |
155 | 155 | { 0x50, 0xd5 }, { 0x51, 0x01 }, | |
156 | { 0x50, 0xd6 }, { 0x51, 0x1f }, | 156 | { 0x50, 0xd6 }, { 0x51, 0x1f }, |
157 | { 0x50, 0xd2 }, { 0x51, 0x03 }, | 157 | { 0x50, 0xd2 }, { 0x51, 0x03 }, |
158 | { 0x50, 0xd7 }, { 0x51, 0xbf }, | 158 | { 0x50, 0xd7 }, { 0x51, 0x3f }, |
159 | { 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff }, | ||
160 | { 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c }, | ||
161 | |||
162 | { 0x04, 0x40 }, { 0x05, 0x00 }, | ||
163 | { 0x28, 0x00 }, { 0x2b, 0x08 }, | ||
164 | { 0x28, 0x05 }, { 0x2b, 0x00 }, | ||
165 | { 0x1c, 0x01 }, | 159 | { 0x1c, 0x01 }, |
166 | { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f }, | 160 | { 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 }, |
167 | { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 }, | 161 | { 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d }, |
168 | { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 }, | 162 | { 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, |
169 | { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 }, | 163 | { 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 }, |
170 | { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 }, | 164 | { 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 }, |
171 | { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 }, | 165 | { 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 }, |
172 | { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 }, | 166 | { 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, |
173 | { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 }, | 167 | { 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 }, |
174 | { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b }, | 168 | { 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e }, |
175 | { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 }, | 169 | { 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e }, |
176 | { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d }, | 170 | { 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 }, |
177 | { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 }, | 171 | { 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, |
178 | { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b }, | 172 | { 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 }, |
179 | { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, | 173 | { 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 }, |
180 | { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 }, | 174 | { 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe }, |
181 | { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 }, | 175 | { 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 }, |
182 | { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 }, | 176 | { 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee }, |
183 | { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 }, | 177 | { 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 }, |
184 | { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f }, | 178 | { 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f }, |
185 | { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef }, | 179 | { 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 }, |
186 | { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 }, | 180 | { 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 }, |
187 | { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 }, | 181 | { 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a }, |
188 | { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d }, | 182 | { 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc }, |
189 | { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 }, | 183 | { 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba }, |
190 | { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba }, | 184 | { 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 }, |
191 | { 0x50, 0x1e }, { 0x51, 0x5d }, | 185 | { 0x50, 0x1e }, { 0x51, 0x5d }, |
192 | { 0x50, 0x22 }, { 0x51, 0x00 }, | 186 | { 0x50, 0x22 }, { 0x51, 0x00 }, |
193 | { 0x50, 0x23 }, { 0x51, 0xc8 }, | 187 | { 0x50, 0x23 }, { 0x51, 0xc8 }, |
@@ -196,9 +190,7 @@ static struct regdata mb86a20s_init2[] = { | |||
196 | { 0x50, 0x26 }, { 0x51, 0x00 }, | 190 | { 0x50, 0x26 }, { 0x51, 0x00 }, |
197 | { 0x50, 0x27 }, { 0x51, 0xc3 }, | 191 | { 0x50, 0x27 }, { 0x51, 0xc3 }, |
198 | { 0x50, 0x39 }, { 0x51, 0x02 }, | 192 | { 0x50, 0x39 }, { 0x51, 0x02 }, |
199 | { 0xec, 0x0f }, | 193 | { 0x50, 0xd5 }, { 0x51, 0x01 }, |
200 | { 0xeb, 0x1f }, | ||
201 | { 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 }, | ||
202 | { 0xd0, 0x00 }, | 194 | { 0xd0, 0x00 }, |
203 | }; | 195 | }; |
204 | 196 | ||
@@ -318,7 +310,11 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, enum fe_status *status) | |||
318 | if (val >= 7) | 310 | if (val >= 7) |
319 | *status |= FE_HAS_SYNC; | 311 | *status |= FE_HAS_SYNC; |
320 | 312 | ||
321 | if (val >= 8) /* Maybe 9? */ | 313 | /* |
314 | * Actually, on state S8, it starts receiving TS, but the TS | ||
315 | * output is only on normal state after the transition to S9. | ||
316 | */ | ||
317 | if (val >= 9) | ||
322 | *status |= FE_HAS_LOCK; | 318 | *status |= FE_HAS_LOCK; |
323 | 319 | ||
324 | dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n", | 320 | dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n", |
@@ -2058,6 +2054,11 @@ static void mb86a20s_release(struct dvb_frontend *fe) | |||
2058 | kfree(state); | 2054 | kfree(state); |
2059 | } | 2055 | } |
2060 | 2056 | ||
2057 | static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe) | ||
2058 | { | ||
2059 | return DVBFE_ALGO_HW; | ||
2060 | } | ||
2061 | |||
2061 | static struct dvb_frontend_ops mb86a20s_ops; | 2062 | static struct dvb_frontend_ops mb86a20s_ops; |
2062 | 2063 | ||
2063 | struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, | 2064 | struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, |
@@ -2130,6 +2131,7 @@ static struct dvb_frontend_ops mb86a20s_ops = { | |||
2130 | .read_status = mb86a20s_read_status_and_stats, | 2131 | .read_status = mb86a20s_read_status_and_stats, |
2131 | .read_signal_strength = mb86a20s_read_signal_strength_from_cache, | 2132 | .read_signal_strength = mb86a20s_read_signal_strength_from_cache, |
2132 | .tune = mb86a20s_tune, | 2133 | .tune = mb86a20s_tune, |
2134 | .get_frontend_algo = mb86a20s_get_frontend_algo, | ||
2133 | }; | 2135 | }; |
2134 | 2136 | ||
2135 | MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware"); | 2137 | MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware"); |
diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index 8bf716a8ea58..78669ea68c61 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/string.h> | 25 | #include <linux/string.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/firmware.h> | 27 | #include <linux/firmware.h> |
28 | #include <linux/regmap.h> | ||
28 | 29 | ||
29 | #include "dvb_frontend.h" | 30 | #include "dvb_frontend.h" |
30 | #include "dvb_math.h" | 31 | #include "dvb_math.h" |
@@ -40,7 +41,9 @@ | |||
40 | */ | 41 | */ |
41 | 42 | ||
42 | struct si2165_state { | 43 | struct si2165_state { |
43 | struct i2c_adapter *i2c; | 44 | struct i2c_client *client; |
45 | |||
46 | struct regmap *regmap; | ||
44 | 47 | ||
45 | struct dvb_frontend fe; | 48 | struct dvb_frontend fe; |
46 | 49 | ||
@@ -108,61 +111,27 @@ static int si2165_write(struct si2165_state *state, const u16 reg, | |||
108 | const u8 *src, const int count) | 111 | const u8 *src, const int count) |
109 | { | 112 | { |
110 | int ret; | 113 | int ret; |
111 | struct i2c_msg msg; | ||
112 | u8 buf[2 + 4]; /* write a maximum of 4 bytes of data */ | ||
113 | |||
114 | if (count + 2 > sizeof(buf)) { | ||
115 | dev_warn(&state->i2c->dev, | ||
116 | "%s: i2c wr reg=%04x: count=%d is too big!\n", | ||
117 | KBUILD_MODNAME, reg, count); | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | buf[0] = reg >> 8; | ||
121 | buf[1] = reg & 0xff; | ||
122 | memcpy(buf + 2, src, count); | ||
123 | |||
124 | msg.addr = state->config.i2c_addr; | ||
125 | msg.flags = 0; | ||
126 | msg.buf = buf; | ||
127 | msg.len = count + 2; | ||
128 | 114 | ||
129 | if (debug & DEBUG_I2C_WRITE) | 115 | if (debug & DEBUG_I2C_WRITE) |
130 | deb_i2c_write("reg: 0x%04x, data: %*ph\n", reg, count, src); | 116 | deb_i2c_write("reg: 0x%04x, data: %*ph\n", reg, count, src); |
131 | 117 | ||
132 | ret = i2c_transfer(state->i2c, &msg, 1); | 118 | ret = regmap_bulk_write(state->regmap, reg, src, count); |
133 | 119 | ||
134 | if (ret != 1) { | 120 | if (ret) |
135 | dev_err(&state->i2c->dev, "%s: ret == %d\n", __func__, ret); | 121 | dev_err(&state->client->dev, "%s: ret == %d\n", __func__, ret); |
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | else | ||
139 | return -EREMOTEIO; | ||
140 | } | ||
141 | 122 | ||
142 | return 0; | 123 | return ret; |
143 | } | 124 | } |
144 | 125 | ||
145 | static int si2165_read(struct si2165_state *state, | 126 | static int si2165_read(struct si2165_state *state, |
146 | const u16 reg, u8 *val, const int count) | 127 | const u16 reg, u8 *val, const int count) |
147 | { | 128 | { |
148 | int ret; | 129 | int ret = regmap_bulk_read(state->regmap, reg, val, count); |
149 | u8 reg_buf[] = { reg >> 8, reg & 0xff }; | ||
150 | struct i2c_msg msg[] = { | ||
151 | { .addr = state->config.i2c_addr, | ||
152 | .flags = 0, .buf = reg_buf, .len = 2 }, | ||
153 | { .addr = state->config.i2c_addr, | ||
154 | .flags = I2C_M_RD, .buf = val, .len = count }, | ||
155 | }; | ||
156 | |||
157 | ret = i2c_transfer(state->i2c, msg, 2); | ||
158 | 130 | ||
159 | if (ret != 2) { | 131 | if (ret) { |
160 | dev_err(&state->i2c->dev, "%s: error (addr %02x reg %04x error (ret == %i)\n", | 132 | dev_err(&state->client->dev, "%s: error (addr %02x reg %04x error (ret == %i)\n", |
161 | __func__, state->config.i2c_addr, reg, ret); | 133 | __func__, state->config.i2c_addr, reg, ret); |
162 | if (ret < 0) | 134 | return ret; |
163 | return ret; | ||
164 | else | ||
165 | return -EREMOTEIO; | ||
166 | } | 135 | } |
167 | 136 | ||
168 | if (debug & DEBUG_I2C_READ) | 137 | if (debug & DEBUG_I2C_READ) |
@@ -174,9 +143,9 @@ static int si2165_read(struct si2165_state *state, | |||
174 | static int si2165_readreg8(struct si2165_state *state, | 143 | static int si2165_readreg8(struct si2165_state *state, |
175 | const u16 reg, u8 *val) | 144 | const u16 reg, u8 *val) |
176 | { | 145 | { |
177 | int ret; | 146 | unsigned int val_tmp; |
178 | 147 | int ret = regmap_read(state->regmap, reg, &val_tmp); | |
179 | ret = si2165_read(state, reg, val, 1); | 148 | *val = (u8)val_tmp; |
180 | deb_readreg("R(0x%04x)=0x%02x\n", reg, *val); | 149 | deb_readreg("R(0x%04x)=0x%02x\n", reg, *val); |
181 | return ret; | 150 | return ret; |
182 | } | 151 | } |
@@ -194,7 +163,7 @@ static int si2165_readreg16(struct si2165_state *state, | |||
194 | 163 | ||
195 | static int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val) | 164 | static int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val) |
196 | { | 165 | { |
197 | return si2165_write(state, reg, &val, 1); | 166 | return regmap_write(state->regmap, reg, val); |
198 | } | 167 | } |
199 | 168 | ||
200 | static int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val) | 169 | static int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val) |
@@ -345,7 +314,7 @@ static int si2165_wait_init_done(struct si2165_state *state) | |||
345 | return 0; | 314 | return 0; |
346 | usleep_range(1000, 50000); | 315 | usleep_range(1000, 50000); |
347 | } | 316 | } |
348 | dev_err(&state->i2c->dev, "%s: init_done was not set\n", | 317 | dev_err(&state->client->dev, "%s: init_done was not set\n", |
349 | KBUILD_MODNAME); | 318 | KBUILD_MODNAME); |
350 | return ret; | 319 | return ret; |
351 | } | 320 | } |
@@ -374,14 +343,14 @@ static int si2165_upload_firmware_block(struct si2165_state *state, | |||
374 | wordcount = data[offset]; | 343 | wordcount = data[offset]; |
375 | if (wordcount < 1 || data[offset+1] || | 344 | if (wordcount < 1 || data[offset+1] || |
376 | data[offset+2] || data[offset+3]) { | 345 | data[offset+2] || data[offset+3]) { |
377 | dev_warn(&state->i2c->dev, | 346 | dev_warn(&state->client->dev, |
378 | "%s: bad fw data[0..3] = %*ph\n", | 347 | "%s: bad fw data[0..3] = %*ph\n", |
379 | KBUILD_MODNAME, 4, data); | 348 | KBUILD_MODNAME, 4, data); |
380 | return -EINVAL; | 349 | return -EINVAL; |
381 | } | 350 | } |
382 | 351 | ||
383 | if (offset + 8 + wordcount * 4 > len) { | 352 | if (offset + 8 + wordcount * 4 > len) { |
384 | dev_warn(&state->i2c->dev, | 353 | dev_warn(&state->client->dev, |
385 | "%s: len is too small for block len=%d, wordcount=%d\n", | 354 | "%s: len is too small for block len=%d, wordcount=%d\n", |
386 | KBUILD_MODNAME, len, wordcount); | 355 | KBUILD_MODNAME, len, wordcount); |
387 | return -EINVAL; | 356 | return -EINVAL; |
@@ -444,15 +413,15 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
444 | fw_file = SI2165_FIRMWARE_REV_D; | 413 | fw_file = SI2165_FIRMWARE_REV_D; |
445 | break; | 414 | break; |
446 | default: | 415 | default: |
447 | dev_info(&state->i2c->dev, "%s: no firmware file for revision=%d\n", | 416 | dev_info(&state->client->dev, "%s: no firmware file for revision=%d\n", |
448 | KBUILD_MODNAME, state->chip_revcode); | 417 | KBUILD_MODNAME, state->chip_revcode); |
449 | return 0; | 418 | return 0; |
450 | } | 419 | } |
451 | 420 | ||
452 | /* request the firmware, this will block and timeout */ | 421 | /* request the firmware, this will block and timeout */ |
453 | ret = request_firmware(&fw, fw_file, state->i2c->dev.parent); | 422 | ret = request_firmware(&fw, fw_file, &state->client->dev); |
454 | if (ret) { | 423 | if (ret) { |
455 | dev_warn(&state->i2c->dev, "%s: firmware file '%s' not found\n", | 424 | dev_warn(&state->client->dev, "%s: firmware file '%s' not found\n", |
456 | KBUILD_MODNAME, fw_file); | 425 | KBUILD_MODNAME, fw_file); |
457 | goto error; | 426 | goto error; |
458 | } | 427 | } |
@@ -460,11 +429,11 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
460 | data = fw->data; | 429 | data = fw->data; |
461 | len = fw->size; | 430 | len = fw->size; |
462 | 431 | ||
463 | dev_info(&state->i2c->dev, "%s: downloading firmware from file '%s' size=%d\n", | 432 | dev_info(&state->client->dev, "%s: downloading firmware from file '%s' size=%d\n", |
464 | KBUILD_MODNAME, fw_file, len); | 433 | KBUILD_MODNAME, fw_file, len); |
465 | 434 | ||
466 | if (len % 4 != 0) { | 435 | if (len % 4 != 0) { |
467 | dev_warn(&state->i2c->dev, "%s: firmware size is not multiple of 4\n", | 436 | dev_warn(&state->client->dev, "%s: firmware size is not multiple of 4\n", |
468 | KBUILD_MODNAME); | 437 | KBUILD_MODNAME); |
469 | ret = -EINVAL; | 438 | ret = -EINVAL; |
470 | goto error; | 439 | goto error; |
@@ -472,14 +441,14 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
472 | 441 | ||
473 | /* check header (8 bytes) */ | 442 | /* check header (8 bytes) */ |
474 | if (len < 8) { | 443 | if (len < 8) { |
475 | dev_warn(&state->i2c->dev, "%s: firmware header is missing\n", | 444 | dev_warn(&state->client->dev, "%s: firmware header is missing\n", |
476 | KBUILD_MODNAME); | 445 | KBUILD_MODNAME); |
477 | ret = -EINVAL; | 446 | ret = -EINVAL; |
478 | goto error; | 447 | goto error; |
479 | } | 448 | } |
480 | 449 | ||
481 | if (data[0] != 1 || data[1] != 0) { | 450 | if (data[0] != 1 || data[1] != 0) { |
482 | dev_warn(&state->i2c->dev, "%s: firmware file version is wrong\n", | 451 | dev_warn(&state->client->dev, "%s: firmware file version is wrong\n", |
483 | KBUILD_MODNAME); | 452 | KBUILD_MODNAME); |
484 | ret = -EINVAL; | 453 | ret = -EINVAL; |
485 | goto error; | 454 | goto error; |
@@ -517,7 +486,7 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
517 | /* start right after the header */ | 486 | /* start right after the header */ |
518 | offset = 8; | 487 | offset = 8; |
519 | 488 | ||
520 | dev_info(&state->i2c->dev, "%s: si2165_upload_firmware extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n", | 489 | dev_info(&state->client->dev, "%s: si2165_upload_firmware extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n", |
521 | KBUILD_MODNAME, patch_version, block_count, crc_expected); | 490 | KBUILD_MODNAME, patch_version, block_count, crc_expected); |
522 | 491 | ||
523 | ret = si2165_upload_firmware_block(state, data, len, &offset, 1); | 492 | ret = si2165_upload_firmware_block(state, data, len, &offset, 1); |
@@ -536,7 +505,7 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
536 | ret = si2165_upload_firmware_block(state, data, len, | 505 | ret = si2165_upload_firmware_block(state, data, len, |
537 | &offset, block_count); | 506 | &offset, block_count); |
538 | if (ret < 0) { | 507 | if (ret < 0) { |
539 | dev_err(&state->i2c->dev, | 508 | dev_err(&state->client->dev, |
540 | "%s: firmware could not be uploaded\n", | 509 | "%s: firmware could not be uploaded\n", |
541 | KBUILD_MODNAME); | 510 | KBUILD_MODNAME); |
542 | goto error; | 511 | goto error; |
@@ -548,7 +517,7 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
548 | goto error; | 517 | goto error; |
549 | 518 | ||
550 | if (val16 != crc_expected) { | 519 | if (val16 != crc_expected) { |
551 | dev_err(&state->i2c->dev, | 520 | dev_err(&state->client->dev, |
552 | "%s: firmware crc mismatch %04x != %04x\n", | 521 | "%s: firmware crc mismatch %04x != %04x\n", |
553 | KBUILD_MODNAME, val16, crc_expected); | 522 | KBUILD_MODNAME, val16, crc_expected); |
554 | ret = -EINVAL; | 523 | ret = -EINVAL; |
@@ -560,7 +529,7 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
560 | goto error; | 529 | goto error; |
561 | 530 | ||
562 | if (len != offset) { | 531 | if (len != offset) { |
563 | dev_err(&state->i2c->dev, | 532 | dev_err(&state->client->dev, |
564 | "%s: firmware len mismatch %04x != %04x\n", | 533 | "%s: firmware len mismatch %04x != %04x\n", |
565 | KBUILD_MODNAME, len, offset); | 534 | KBUILD_MODNAME, len, offset); |
566 | ret = -EINVAL; | 535 | ret = -EINVAL; |
@@ -577,7 +546,7 @@ static int si2165_upload_firmware(struct si2165_state *state) | |||
577 | if (ret < 0) | 546 | if (ret < 0) |
578 | goto error; | 547 | goto error; |
579 | 548 | ||
580 | dev_info(&state->i2c->dev, "%s: fw load finished\n", KBUILD_MODNAME); | 549 | dev_info(&state->client->dev, "%s: fw load finished\n", KBUILD_MODNAME); |
581 | 550 | ||
582 | ret = 0; | 551 | ret = 0; |
583 | state->firmware_loaded = true; | 552 | state->firmware_loaded = true; |
@@ -611,7 +580,7 @@ static int si2165_init(struct dvb_frontend *fe) | |||
611 | if (ret < 0) | 580 | if (ret < 0) |
612 | goto error; | 581 | goto error; |
613 | if (val != state->config.chip_mode) { | 582 | if (val != state->config.chip_mode) { |
614 | dev_err(&state->i2c->dev, "%s: could not set chip_mode\n", | 583 | dev_err(&state->client->dev, "%s: could not set chip_mode\n", |
615 | KBUILD_MODNAME); | 584 | KBUILD_MODNAME); |
616 | return -EINVAL; | 585 | return -EINVAL; |
617 | } | 586 | } |
@@ -751,6 +720,9 @@ static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate) | |||
751 | u64 oversamp; | 720 | u64 oversamp; |
752 | u32 reg_value; | 721 | u32 reg_value; |
753 | 722 | ||
723 | if (!dvb_rate) | ||
724 | return -EINVAL; | ||
725 | |||
754 | oversamp = si2165_get_fe_clk(state); | 726 | oversamp = si2165_get_fe_clk(state); |
755 | oversamp <<= 23; | 727 | oversamp <<= 23; |
756 | do_div(oversamp, dvb_rate); | 728 | do_div(oversamp, dvb_rate); |
@@ -769,12 +741,15 @@ static int si2165_set_if_freq_shift(struct si2165_state *state) | |||
769 | u32 IF = 0; | 741 | u32 IF = 0; |
770 | 742 | ||
771 | if (!fe->ops.tuner_ops.get_if_frequency) { | 743 | if (!fe->ops.tuner_ops.get_if_frequency) { |
772 | dev_err(&state->i2c->dev, | 744 | dev_err(&state->client->dev, |
773 | "%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n", | 745 | "%s: Error: get_if_frequency() not defined at tuner. Can't work without it!\n", |
774 | KBUILD_MODNAME); | 746 | KBUILD_MODNAME); |
775 | return -EINVAL; | 747 | return -EINVAL; |
776 | } | 748 | } |
777 | 749 | ||
750 | if (!fe_clk) | ||
751 | return -EINVAL; | ||
752 | |||
778 | fe->ops.tuner_ops.get_if_frequency(fe, &IF); | 753 | fe->ops.tuner_ops.get_if_frequency(fe, &IF); |
779 | if_freq_shift = IF; | 754 | if_freq_shift = IF; |
780 | if_freq_shift <<= 29; | 755 | if_freq_shift <<= 29; |
@@ -1003,14 +978,6 @@ static int si2165_set_frontend(struct dvb_frontend *fe) | |||
1003 | return 0; | 978 | return 0; |
1004 | } | 979 | } |
1005 | 980 | ||
1006 | static void si2165_release(struct dvb_frontend *fe) | ||
1007 | { | ||
1008 | struct si2165_state *state = fe->demodulator_priv; | ||
1009 | |||
1010 | dprintk("%s: called\n", __func__); | ||
1011 | kfree(state); | ||
1012 | } | ||
1013 | |||
1014 | static struct dvb_frontend_ops si2165_ops = { | 981 | static struct dvb_frontend_ops si2165_ops = { |
1015 | .info = { | 982 | .info = { |
1016 | .name = "Silicon Labs ", | 983 | .name = "Silicon Labs ", |
@@ -1046,67 +1013,83 @@ static struct dvb_frontend_ops si2165_ops = { | |||
1046 | 1013 | ||
1047 | .set_frontend = si2165_set_frontend, | 1014 | .set_frontend = si2165_set_frontend, |
1048 | .read_status = si2165_read_status, | 1015 | .read_status = si2165_read_status, |
1049 | |||
1050 | .release = si2165_release, | ||
1051 | }; | 1016 | }; |
1052 | 1017 | ||
1053 | struct dvb_frontend *si2165_attach(const struct si2165_config *config, | 1018 | static int si2165_probe(struct i2c_client *client, |
1054 | struct i2c_adapter *i2c) | 1019 | const struct i2c_device_id *id) |
1055 | { | 1020 | { |
1056 | struct si2165_state *state = NULL; | 1021 | struct si2165_state *state = NULL; |
1022 | struct si2165_platform_data *pdata = client->dev.platform_data; | ||
1057 | int n; | 1023 | int n; |
1058 | int io_ret; | 1024 | int ret = 0; |
1059 | u8 val; | 1025 | u8 val; |
1060 | char rev_char; | 1026 | char rev_char; |
1061 | const char *chip_name; | 1027 | const char *chip_name; |
1062 | 1028 | static const struct regmap_config regmap_config = { | |
1063 | if (config == NULL || i2c == NULL) | 1029 | .reg_bits = 16, |
1064 | goto error; | 1030 | .val_bits = 8, |
1031 | .max_register = 0x08ff, | ||
1032 | }; | ||
1065 | 1033 | ||
1066 | /* allocate memory for the internal state */ | 1034 | /* allocate memory for the internal state */ |
1067 | state = kzalloc(sizeof(struct si2165_state), GFP_KERNEL); | 1035 | state = kzalloc(sizeof(struct si2165_state), GFP_KERNEL); |
1068 | if (state == NULL) | 1036 | if (state == NULL) { |
1037 | ret = -ENOMEM; | ||
1069 | goto error; | 1038 | goto error; |
1039 | } | ||
1040 | |||
1041 | /* create regmap */ | ||
1042 | state->regmap = devm_regmap_init_i2c(client, ®map_config); | ||
1043 | if (IS_ERR(state->regmap)) { | ||
1044 | ret = PTR_ERR(state->regmap); | ||
1045 | goto error; | ||
1046 | } | ||
1070 | 1047 | ||
1071 | /* setup the state */ | 1048 | /* setup the state */ |
1072 | state->i2c = i2c; | 1049 | state->client = client; |
1073 | state->config = *config; | 1050 | state->config.i2c_addr = client->addr; |
1051 | state->config.chip_mode = pdata->chip_mode; | ||
1052 | state->config.ref_freq_Hz = pdata->ref_freq_Hz; | ||
1053 | state->config.inversion = pdata->inversion; | ||
1074 | 1054 | ||
1075 | if (state->config.ref_freq_Hz < 4000000 | 1055 | if (state->config.ref_freq_Hz < 4000000 |
1076 | || state->config.ref_freq_Hz > 27000000) { | 1056 | || state->config.ref_freq_Hz > 27000000) { |
1077 | dev_err(&state->i2c->dev, "%s: ref_freq of %d Hz not supported by this driver\n", | 1057 | dev_err(&state->client->dev, "%s: ref_freq of %d Hz not supported by this driver\n", |
1078 | KBUILD_MODNAME, state->config.ref_freq_Hz); | 1058 | KBUILD_MODNAME, state->config.ref_freq_Hz); |
1059 | ret = -EINVAL; | ||
1079 | goto error; | 1060 | goto error; |
1080 | } | 1061 | } |
1081 | 1062 | ||
1082 | /* create dvb_frontend */ | 1063 | /* create dvb_frontend */ |
1083 | memcpy(&state->fe.ops, &si2165_ops, | 1064 | memcpy(&state->fe.ops, &si2165_ops, |
1084 | sizeof(struct dvb_frontend_ops)); | 1065 | sizeof(struct dvb_frontend_ops)); |
1066 | state->fe.ops.release = NULL; | ||
1085 | state->fe.demodulator_priv = state; | 1067 | state->fe.demodulator_priv = state; |
1068 | i2c_set_clientdata(client, state); | ||
1086 | 1069 | ||
1087 | /* powerup */ | 1070 | /* powerup */ |
1088 | io_ret = si2165_writereg8(state, 0x0000, state->config.chip_mode); | 1071 | ret = si2165_writereg8(state, 0x0000, state->config.chip_mode); |
1089 | if (io_ret < 0) | 1072 | if (ret < 0) |
1090 | goto error; | 1073 | goto nodev_error; |
1091 | 1074 | ||
1092 | io_ret = si2165_readreg8(state, 0x0000, &val); | 1075 | ret = si2165_readreg8(state, 0x0000, &val); |
1093 | if (io_ret < 0) | 1076 | if (ret < 0) |
1094 | goto error; | 1077 | goto nodev_error; |
1095 | if (val != state->config.chip_mode) | 1078 | if (val != state->config.chip_mode) |
1096 | goto error; | 1079 | goto nodev_error; |
1097 | 1080 | ||
1098 | io_ret = si2165_readreg8(state, 0x0023, &state->chip_revcode); | 1081 | ret = si2165_readreg8(state, 0x0023, &state->chip_revcode); |
1099 | if (io_ret < 0) | 1082 | if (ret < 0) |
1100 | goto error; | 1083 | goto nodev_error; |
1101 | 1084 | ||
1102 | io_ret = si2165_readreg8(state, 0x0118, &state->chip_type); | 1085 | ret = si2165_readreg8(state, 0x0118, &state->chip_type); |
1103 | if (io_ret < 0) | 1086 | if (ret < 0) |
1104 | goto error; | 1087 | goto nodev_error; |
1105 | 1088 | ||
1106 | /* powerdown */ | 1089 | /* powerdown */ |
1107 | io_ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF); | 1090 | ret = si2165_writereg8(state, 0x0000, SI2165_MODE_OFF); |
1108 | if (io_ret < 0) | 1091 | if (ret < 0) |
1109 | goto error; | 1092 | goto nodev_error; |
1110 | 1093 | ||
1111 | if (state->chip_revcode < 26) | 1094 | if (state->chip_revcode < 26) |
1112 | rev_char = 'A' + state->chip_revcode; | 1095 | rev_char = 'A' + state->chip_revcode; |
@@ -1124,12 +1107,12 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config, | |||
1124 | state->has_dvbc = true; | 1107 | state->has_dvbc = true; |
1125 | break; | 1108 | break; |
1126 | default: | 1109 | default: |
1127 | dev_err(&state->i2c->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n", | 1110 | dev_err(&state->client->dev, "%s: Unsupported Silicon Labs chip (type %d, rev %d)\n", |
1128 | KBUILD_MODNAME, state->chip_type, state->chip_revcode); | 1111 | KBUILD_MODNAME, state->chip_type, state->chip_revcode); |
1129 | goto error; | 1112 | goto nodev_error; |
1130 | } | 1113 | } |
1131 | 1114 | ||
1132 | dev_info(&state->i2c->dev, | 1115 | dev_info(&state->client->dev, |
1133 | "%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n", | 1116 | "%s: Detected Silicon Labs %s-%c (type %d, rev %d)\n", |
1134 | KBUILD_MODNAME, chip_name, rev_char, state->chip_type, | 1117 | KBUILD_MODNAME, chip_name, rev_char, state->chip_type, |
1135 | state->chip_revcode); | 1118 | state->chip_revcode); |
@@ -1149,13 +1132,46 @@ struct dvb_frontend *si2165_attach(const struct si2165_config *config, | |||
1149 | sizeof(state->fe.ops.info.name)); | 1132 | sizeof(state->fe.ops.info.name)); |
1150 | } | 1133 | } |
1151 | 1134 | ||
1152 | return &state->fe; | 1135 | /* return fe pointer */ |
1136 | *pdata->fe = &state->fe; | ||
1137 | |||
1138 | return 0; | ||
1153 | 1139 | ||
1140 | nodev_error: | ||
1141 | ret = -ENODEV; | ||
1154 | error: | 1142 | error: |
1155 | kfree(state); | 1143 | kfree(state); |
1156 | return NULL; | 1144 | dev_dbg(&client->dev, "failed=%d\n", ret); |
1145 | return ret; | ||
1157 | } | 1146 | } |
1158 | EXPORT_SYMBOL(si2165_attach); | 1147 | |
1148 | static int si2165_remove(struct i2c_client *client) | ||
1149 | { | ||
1150 | struct si2165_state *state = i2c_get_clientdata(client); | ||
1151 | |||
1152 | dev_dbg(&client->dev, "\n"); | ||
1153 | |||
1154 | kfree(state); | ||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | static const struct i2c_device_id si2165_id_table[] = { | ||
1159 | {"si2165", 0}, | ||
1160 | {} | ||
1161 | }; | ||
1162 | MODULE_DEVICE_TABLE(i2c, si2165_id_table); | ||
1163 | |||
1164 | static struct i2c_driver si2165_driver = { | ||
1165 | .driver = { | ||
1166 | .owner = THIS_MODULE, | ||
1167 | .name = "si2165", | ||
1168 | }, | ||
1169 | .probe = si2165_probe, | ||
1170 | .remove = si2165_remove, | ||
1171 | .id_table = si2165_id_table, | ||
1172 | }; | ||
1173 | |||
1174 | module_i2c_driver(si2165_driver); | ||
1159 | 1175 | ||
1160 | module_param(debug, int, 0644); | 1176 | module_param(debug, int, 0644); |
1161 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 1177 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
diff --git a/drivers/media/dvb-frontends/si2165.h b/drivers/media/dvb-frontends/si2165.h index 8a15d6a9c552..76c2ca7d7edb 100644 --- a/drivers/media/dvb-frontends/si2165.h +++ b/drivers/media/dvb-frontends/si2165.h | |||
@@ -28,10 +28,15 @@ enum { | |||
28 | SI2165_MODE_PLL_XTAL = 0x21 | 28 | SI2165_MODE_PLL_XTAL = 0x21 |
29 | }; | 29 | }; |
30 | 30 | ||
31 | struct si2165_config { | 31 | /* I2C addresses |
32 | /* i2c addr | 32 | * possible values: 0x64,0x65,0x66,0x67 |
33 | * possible values: 0x64,0x65,0x66,0x67 */ | 33 | */ |
34 | u8 i2c_addr; | 34 | struct si2165_platform_data { |
35 | /* | ||
36 | * frontend | ||
37 | * returned by driver | ||
38 | */ | ||
39 | struct dvb_frontend **fe; | ||
35 | 40 | ||
36 | /* external clock or XTAL */ | 41 | /* external clock or XTAL */ |
37 | u8 chip_mode; | 42 | u8 chip_mode; |
@@ -45,18 +50,4 @@ struct si2165_config { | |||
45 | bool inversion; | 50 | bool inversion; |
46 | }; | 51 | }; |
47 | 52 | ||
48 | #if IS_REACHABLE(CONFIG_DVB_SI2165) | ||
49 | struct dvb_frontend *si2165_attach( | ||
50 | const struct si2165_config *config, | ||
51 | struct i2c_adapter *i2c); | ||
52 | #else | ||
53 | static inline struct dvb_frontend *si2165_attach( | ||
54 | const struct si2165_config *config, | ||
55 | struct i2c_adapter *i2c) | ||
56 | { | ||
57 | pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||
58 | return NULL; | ||
59 | } | ||
60 | #endif /* CONFIG_DVB_SI2165 */ | ||
61 | |||
62 | #endif /* _DVB_SI2165_H */ | 53 | #endif /* _DVB_SI2165_H */ |
diff --git a/drivers/media/dvb-frontends/si2165_priv.h b/drivers/media/dvb-frontends/si2165_priv.h index 2b70cf12cd79..e5932118834b 100644 --- a/drivers/media/dvb-frontends/si2165_priv.h +++ b/drivers/media/dvb-frontends/si2165_priv.h | |||
@@ -20,4 +20,21 @@ | |||
20 | 20 | ||
21 | #define SI2165_FIRMWARE_REV_D "dvb-demod-si2165.fw" | 21 | #define SI2165_FIRMWARE_REV_D "dvb-demod-si2165.fw" |
22 | 22 | ||
23 | struct si2165_config { | ||
24 | /* i2c addr | ||
25 | * possible values: 0x64,0x65,0x66,0x67 */ | ||
26 | u8 i2c_addr; | ||
27 | |||
28 | /* external clock or XTAL */ | ||
29 | u8 chip_mode; | ||
30 | |||
31 | /* frequency of external clock or xtal in Hz | ||
32 | * possible values: 4000000, 16000000, 20000000, 240000000, 27000000 | ||
33 | */ | ||
34 | u32 ref_freq_Hz; | ||
35 | |||
36 | /* invert the spectrum */ | ||
37 | bool inversion; | ||
38 | }; | ||
39 | |||
23 | #endif /* _DVB_SI2165_PRIV */ | 40 | #endif /* _DVB_SI2165_PRIV */ |
diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c index a0c3c526b132..73347d51f340 100644 --- a/drivers/media/dvb-frontends/stb6000.c +++ b/drivers/media/dvb-frontends/stb6000.c | |||
@@ -186,7 +186,7 @@ static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
186 | return 0; | 186 | return 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | static struct dvb_tuner_ops stb6000_tuner_ops = { | 189 | static const struct dvb_tuner_ops stb6000_tuner_ops = { |
190 | .info = { | 190 | .info = { |
191 | .name = "ST STB6000", | 191 | .name = "ST STB6000", |
192 | .frequency_min = 950000, | 192 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c index b9c2511bf019..5add1182c3ca 100644 --- a/drivers/media/dvb-frontends/stb6100.c +++ b/drivers/media/dvb-frontends/stb6100.c | |||
@@ -522,7 +522,7 @@ static int stb6100_set_params(struct dvb_frontend *fe) | |||
522 | return 0; | 522 | return 0; |
523 | } | 523 | } |
524 | 524 | ||
525 | static struct dvb_tuner_ops stb6100_ops = { | 525 | static const struct dvb_tuner_ops stb6100_ops = { |
526 | .info = { | 526 | .info = { |
527 | .name = "STB6100 Silicon Tuner", | 527 | .name = "STB6100 Silicon Tuner", |
528 | .frequency_min = 950000, | 528 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c index 91c6dcf65d2a..66a5a7f2295c 100644 --- a/drivers/media/dvb-frontends/stv6110.c +++ b/drivers/media/dvb-frontends/stv6110.c | |||
@@ -382,7 +382,7 @@ static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
382 | return 0; | 382 | return 0; |
383 | } | 383 | } |
384 | 384 | ||
385 | static struct dvb_tuner_ops stv6110_tuner_ops = { | 385 | static const struct dvb_tuner_ops stv6110_tuner_ops = { |
386 | .info = { | 386 | .info = { |
387 | .name = "ST STV6110", | 387 | .name = "ST STV6110", |
388 | .frequency_min = 950000, | 388 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c index a62c01e454f5..c611ad210b5c 100644 --- a/drivers/media/dvb-frontends/stv6110x.c +++ b/drivers/media/dvb-frontends/stv6110x.c | |||
@@ -345,7 +345,7 @@ static int stv6110x_release(struct dvb_frontend *fe) | |||
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
348 | static struct dvb_tuner_ops stv6110x_ops = { | 348 | static const struct dvb_tuner_ops stv6110x_ops = { |
349 | .info = { | 349 | .info = { |
350 | .name = "STV6110(A) Silicon Tuner", | 350 | .name = "STV6110(A) Silicon Tuner", |
351 | .frequency_min = 950000, | 351 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c index de0a1c110972..bc247f9b553a 100644 --- a/drivers/media/dvb-frontends/tda18271c2dd.c +++ b/drivers/media/dvb-frontends/tda18271c2dd.c | |||
@@ -1217,7 +1217,7 @@ static int get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | |||
1217 | } | 1217 | } |
1218 | 1218 | ||
1219 | 1219 | ||
1220 | static struct dvb_tuner_ops tuner_ops = { | 1220 | static const struct dvb_tuner_ops tuner_ops = { |
1221 | .info = { | 1221 | .info = { |
1222 | .name = "NXP TDA18271C2D", | 1222 | .name = "NXP TDA18271C2D", |
1223 | .frequency_min = 47125000, | 1223 | .frequency_min = 47125000, |
diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c index 82f8cc534f33..7ca965987f40 100644 --- a/drivers/media/dvb-frontends/tda665x.c +++ b/drivers/media/dvb-frontends/tda665x.c | |||
@@ -206,7 +206,7 @@ static int tda665x_release(struct dvb_frontend *fe) | |||
206 | return 0; | 206 | return 0; |
207 | } | 207 | } |
208 | 208 | ||
209 | static struct dvb_tuner_ops tda665x_ops = { | 209 | static const struct dvb_tuner_ops tda665x_ops = { |
210 | .get_status = tda665x_get_status, | 210 | .get_status = tda665x_get_status, |
211 | .set_params = tda665x_set_params, | 211 | .set_params = tda665x_set_params, |
212 | .get_frequency = tda665x_get_frequency, | 212 | .get_frequency = tda665x_get_frequency, |
diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c index 3285b1bc4642..e0df93191b9e 100644 --- a/drivers/media/dvb-frontends/tda8261.c +++ b/drivers/media/dvb-frontends/tda8261.c | |||
@@ -161,7 +161,7 @@ static int tda8261_release(struct dvb_frontend *fe) | |||
161 | return 0; | 161 | return 0; |
162 | } | 162 | } |
163 | 163 | ||
164 | static struct dvb_tuner_ops tda8261_ops = { | 164 | static const struct dvb_tuner_ops tda8261_ops = { |
165 | 165 | ||
166 | .info = { | 166 | .info = { |
167 | .name = "TDA8261", | 167 | .name = "TDA8261", |
diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c index 04bbcc24de0a..2ec671df1441 100644 --- a/drivers/media/dvb-frontends/tda826x.c +++ b/drivers/media/dvb-frontends/tda826x.c | |||
@@ -129,7 +129,7 @@ static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
129 | return 0; | 129 | return 0; |
130 | } | 130 | } |
131 | 131 | ||
132 | static struct dvb_tuner_ops tda826x_tuner_ops = { | 132 | static const struct dvb_tuner_ops tda826x_tuner_ops = { |
133 | .info = { | 133 | .info = { |
134 | .name = "Philips TDA826X", | 134 | .name = "Philips TDA826X", |
135 | .frequency_min = 950000, | 135 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index 14b410ffe612..a9f6bbea6df3 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c | |||
@@ -496,7 +496,7 @@ static int ts2020_read_signal_strength(struct dvb_frontend *fe, | |||
496 | return 0; | 496 | return 0; |
497 | } | 497 | } |
498 | 498 | ||
499 | static struct dvb_tuner_ops ts2020_tuner_ops = { | 499 | static const struct dvb_tuner_ops ts2020_tuner_ops = { |
500 | .info = { | 500 | .info = { |
501 | .name = "TS2020", | 501 | .name = "TS2020", |
502 | .frequency_min = 950000, | 502 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c index 029384d1fddd..6da12b9e55eb 100644 --- a/drivers/media/dvb-frontends/tua6100.c +++ b/drivers/media/dvb-frontends/tua6100.c | |||
@@ -157,7 +157,7 @@ static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) | |||
157 | return 0; | 157 | return 0; |
158 | } | 158 | } |
159 | 159 | ||
160 | static struct dvb_tuner_ops tua6100_tuner_ops = { | 160 | static const struct dvb_tuner_ops tua6100_tuner_ops = { |
161 | .info = { | 161 | .info = { |
162 | .name = "Infineon TUA6100", | 162 | .name = "Infineon TUA6100", |
163 | .frequency_min = 950000, | 163 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c index 0903d461b8fa..7ed81315965f 100644 --- a/drivers/media/dvb-frontends/zl10036.c +++ b/drivers/media/dvb-frontends/zl10036.c | |||
@@ -446,7 +446,7 @@ static int zl10036_init(struct dvb_frontend *fe) | |||
446 | return ret; | 446 | return ret; |
447 | } | 447 | } |
448 | 448 | ||
449 | static struct dvb_tuner_ops zl10036_tuner_ops = { | 449 | static const struct dvb_tuner_ops zl10036_tuner_ops = { |
450 | .info = { | 450 | .info = { |
451 | .name = "Zarlink ZL10036", | 451 | .name = "Zarlink ZL10036", |
452 | .frequency_min = 950000, | 452 | .frequency_min = 950000, |
diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c index ee09ec26c553..f8c271be196c 100644 --- a/drivers/media/dvb-frontends/zl10039.c +++ b/drivers/media/dvb-frontends/zl10039.c | |||
@@ -255,7 +255,7 @@ static int zl10039_release(struct dvb_frontend *fe) | |||
255 | return 0; | 255 | return 0; |
256 | } | 256 | } |
257 | 257 | ||
258 | static struct dvb_tuner_ops zl10039_ops = { | 258 | static const struct dvb_tuner_ops zl10039_ops = { |
259 | .release = zl10039_release, | 259 | .release = zl10039_release, |
260 | .init = zl10039_init, | 260 | .init = zl10039_init, |
261 | .sleep = zl10039_sleep, | 261 | .sleep = zl10039_sleep, |