Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
[linux-2.6-microblaze.git] / drivers / media / dvb-frontends / ec100.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * E3C EC100 demodulator driver
4  *
5  * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
6  */
7
8 #include <media/dvb_frontend.h>
9 #include "ec100.h"
10
11 struct ec100_state {
12         struct i2c_adapter *i2c;
13         struct dvb_frontend frontend;
14         struct ec100_config config;
15
16         u16 ber;
17 };
18
19 /* write single register */
20 static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
21 {
22         int ret;
23         u8 buf[2] = {reg, val};
24         struct i2c_msg msg[1] = {
25                 {
26                         .addr = state->config.demod_address,
27                         .flags = 0,
28                         .len = sizeof(buf),
29                         .buf = buf,
30                 }
31         };
32
33         ret = i2c_transfer(state->i2c, msg, 1);
34         if (ret == 1) {
35                 ret = 0;
36         } else {
37                 dev_warn(&state->i2c->dev, "%s: i2c wr failed=%d reg=%02x\n",
38                                 KBUILD_MODNAME, ret, reg);
39                 ret = -EREMOTEIO;
40         }
41
42         return ret;
43 }
44
45 /* read single register */
46 static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
47 {
48         int ret;
49         struct i2c_msg msg[2] = {
50                 {
51                         .addr = state->config.demod_address,
52                         .flags = 0,
53                         .len = 1,
54                         .buf = &reg
55                 }, {
56                         .addr = state->config.demod_address,
57                         .flags = I2C_M_RD,
58                         .len = 1,
59                         .buf = val
60                 }
61         };
62
63         ret = i2c_transfer(state->i2c, msg, 2);
64         if (ret == 2) {
65                 ret = 0;
66         } else {
67                 dev_warn(&state->i2c->dev, "%s: i2c rd failed=%d reg=%02x\n",
68                                 KBUILD_MODNAME, ret, reg);
69                 ret = -EREMOTEIO;
70         }
71
72         return ret;
73 }
74
75 static int ec100_set_frontend(struct dvb_frontend *fe)
76 {
77         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
78         struct ec100_state *state = fe->demodulator_priv;
79         int ret;
80         u8 tmp, tmp2;
81
82         dev_dbg(&state->i2c->dev, "%s: frequency=%d bandwidth_hz=%d\n",
83                         __func__, c->frequency, c->bandwidth_hz);
84
85         /* program tuner */
86         if (fe->ops.tuner_ops.set_params)
87                 fe->ops.tuner_ops.set_params(fe);
88
89         ret = ec100_write_reg(state, 0x04, 0x06);
90         if (ret)
91                 goto error;
92         ret = ec100_write_reg(state, 0x67, 0x58);
93         if (ret)
94                 goto error;
95         ret = ec100_write_reg(state, 0x05, 0x18);
96         if (ret)
97                 goto error;
98
99         /* reg/bw |   6  |   7  |   8
100            -------+------+------+------
101            A 0x1b | 0xa1 | 0xe7 | 0x2c
102            A 0x1c | 0x55 | 0x63 | 0x72
103            -------+------+------+------
104            B 0x1b | 0xb7 | 0x00 | 0x49
105            B 0x1c | 0x55 | 0x64 | 0x72 */
106
107         switch (c->bandwidth_hz) {
108         case 6000000:
109                 tmp = 0xb7;
110                 tmp2 = 0x55;
111                 break;
112         case 7000000:
113                 tmp = 0x00;
114                 tmp2 = 0x64;
115                 break;
116         case 8000000:
117         default:
118                 tmp = 0x49;
119                 tmp2 = 0x72;
120         }
121
122         ret = ec100_write_reg(state, 0x1b, tmp);
123         if (ret)
124                 goto error;
125         ret = ec100_write_reg(state, 0x1c, tmp2);
126         if (ret)
127                 goto error;
128
129         ret = ec100_write_reg(state, 0x0c, 0xbb); /* if freq */
130         if (ret)
131                 goto error;
132         ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
133         if (ret)
134                 goto error;
135
136         ret = ec100_write_reg(state, 0x08, 0x24);
137         if (ret)
138                 goto error;
139
140         ret = ec100_write_reg(state, 0x00, 0x00); /* go */
141         if (ret)
142                 goto error;
143         ret = ec100_write_reg(state, 0x00, 0x20); /* go */
144         if (ret)
145                 goto error;
146
147         return ret;
148 error:
149         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
150         return ret;
151 }
152
153 static int ec100_get_tune_settings(struct dvb_frontend *fe,
154         struct dvb_frontend_tune_settings *fesettings)
155 {
156         fesettings->min_delay_ms = 300;
157         fesettings->step_size = 0;
158         fesettings->max_drift = 0;
159
160         return 0;
161 }
162
163 static int ec100_read_status(struct dvb_frontend *fe, enum fe_status *status)
164 {
165         struct ec100_state *state = fe->demodulator_priv;
166         int ret;
167         u8 tmp;
168         *status = 0;
169
170         ret = ec100_read_reg(state, 0x42, &tmp);
171         if (ret)
172                 goto error;
173
174         if (tmp & 0x80) {
175                 /* bit7 set - have lock */
176                 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
177                         FE_HAS_SYNC | FE_HAS_LOCK;
178         } else {
179                 ret = ec100_read_reg(state, 0x01, &tmp);
180                 if (ret)
181                         goto error;
182
183                 if (tmp & 0x10) {
184                         /* bit4 set - have signal */
185                         *status |= FE_HAS_SIGNAL;
186                         if (!(tmp & 0x01)) {
187                                 /* bit0 clear - have ~valid signal */
188                                 *status |= FE_HAS_CARRIER |  FE_HAS_VITERBI;
189                         }
190                 }
191         }
192
193         return ret;
194 error:
195         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
196         return ret;
197 }
198
199 static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
200 {
201         struct ec100_state *state = fe->demodulator_priv;
202         int ret;
203         u8 tmp, tmp2;
204         u16 ber2;
205
206         *ber = 0;
207
208         ret = ec100_read_reg(state, 0x65, &tmp);
209         if (ret)
210                 goto error;
211         ret = ec100_read_reg(state, 0x66, &tmp2);
212         if (ret)
213                 goto error;
214
215         ber2 = (tmp2 << 8) | tmp;
216
217         /* if counter overflow or clear */
218         if (ber2 < state->ber)
219                 *ber = ber2;
220         else
221                 *ber = ber2 - state->ber;
222
223         state->ber = ber2;
224
225         return ret;
226 error:
227         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
228         return ret;
229 }
230
231 static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
232 {
233         struct ec100_state *state = fe->demodulator_priv;
234         int ret;
235         u8 tmp;
236
237         ret = ec100_read_reg(state, 0x24, &tmp);
238         if (ret) {
239                 *strength = 0;
240                 goto error;
241         }
242
243         *strength = ((tmp << 8) | tmp);
244
245         return ret;
246 error:
247         dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
248         return ret;
249 }
250
251 static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
252 {
253         *snr = 0;
254         return 0;
255 }
256
257 static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
258 {
259         *ucblocks = 0;
260         return 0;
261 }
262
263 static void ec100_release(struct dvb_frontend *fe)
264 {
265         struct ec100_state *state = fe->demodulator_priv;
266         kfree(state);
267 }
268
269 static const struct dvb_frontend_ops ec100_ops;
270
271 struct dvb_frontend *ec100_attach(const struct ec100_config *config,
272         struct i2c_adapter *i2c)
273 {
274         int ret;
275         struct ec100_state *state = NULL;
276         u8 tmp;
277
278         /* allocate memory for the internal state */
279         state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
280         if (state == NULL)
281                 goto error;
282
283         /* setup the state */
284         state->i2c = i2c;
285         memcpy(&state->config, config, sizeof(struct ec100_config));
286
287         /* check if the demod is there */
288         ret = ec100_read_reg(state, 0x33, &tmp);
289         if (ret || tmp != 0x0b)
290                 goto error;
291
292         /* create dvb_frontend */
293         memcpy(&state->frontend.ops, &ec100_ops,
294                 sizeof(struct dvb_frontend_ops));
295         state->frontend.demodulator_priv = state;
296
297         return &state->frontend;
298 error:
299         kfree(state);
300         return NULL;
301 }
302 EXPORT_SYMBOL(ec100_attach);
303
304 static const struct dvb_frontend_ops ec100_ops = {
305         .delsys = { SYS_DVBT },
306         .info = {
307                 .name = "E3C EC100 DVB-T",
308                 .caps =
309                         FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
310                         FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
311                         FE_CAN_QPSK | FE_CAN_QAM_16 |
312                         FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
313                         FE_CAN_TRANSMISSION_MODE_AUTO |
314                         FE_CAN_GUARD_INTERVAL_AUTO |
315                         FE_CAN_HIERARCHY_AUTO |
316                         FE_CAN_MUTE_TS
317         },
318
319         .release = ec100_release,
320         .set_frontend = ec100_set_frontend,
321         .get_tune_settings = ec100_get_tune_settings,
322         .read_status = ec100_read_status,
323         .read_ber = ec100_read_ber,
324         .read_signal_strength = ec100_read_signal_strength,
325         .read_snr = ec100_read_snr,
326         .read_ucblocks = ec100_read_ucblocks,
327 };
328
329 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
330 MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
331 MODULE_LICENSE("GPL");