blob: 3a9e4e986fc2db5ca63b2fb677ac474b9b84e09d [file] [log] [blame]
Antti Palosaaric0adca72011-07-08 23:34:09 -03001/*
2 * Realtek RTL2830 DVB-T demodulator driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
Antti Palosaaric0adca72011-07-08 23:34:09 -030016 */
17
18#include "rtl2830_priv.h"
19
Mauro Carvalho Chehab37ebaf62013-11-02 05:11:47 -030020/* Max transfer size done by I2C transfer functions */
21#define MAX_XFER_SIZE 64
22
Antti Palosaari0485a702011-08-04 20:27:19 -030023/* write multiple hardware registers */
Antti Palosaari1f153c42014-12-08 22:47:21 -030024static int rtl2830_wr(struct i2c_client *client, u8 reg, const u8 *val, int len)
Antti Palosaaric0adca72011-07-08 23:34:09 -030025{
26 int ret;
Mauro Carvalho Chehab37ebaf62013-11-02 05:11:47 -030027 u8 buf[MAX_XFER_SIZE];
Antti Palosaaric0adca72011-07-08 23:34:09 -030028 struct i2c_msg msg[1] = {
29 {
Antti Palosaarib8cb50d22014-12-09 00:24:13 -030030 .addr = client->addr,
Antti Palosaaric0adca72011-07-08 23:34:09 -030031 .flags = 0,
Mauro Carvalho Chehab37ebaf62013-11-02 05:11:47 -030032 .len = 1 + len,
Antti Palosaaric0adca72011-07-08 23:34:09 -030033 .buf = buf,
34 }
35 };
36
Mauro Carvalho Chehab37ebaf62013-11-02 05:11:47 -030037 if (1 + len > sizeof(buf)) {
Antti Palosaari7cc39322014-12-08 23:32:19 -030038 dev_warn(&client->dev, "i2c wr reg=%04x: len=%d is too big!\n",
Antti Palosaari947debb2014-12-09 02:31:53 -030039 reg, len);
Mauro Carvalho Chehab37ebaf62013-11-02 05:11:47 -030040 return -EINVAL;
41 }
42
Antti Palosaari0485a702011-08-04 20:27:19 -030043 buf[0] = reg;
44 memcpy(&buf[1], val, len);
Antti Palosaaric0adca72011-07-08 23:34:09 -030045
Antti Palosaarifd4cfa82014-12-09 16:14:41 -030046 ret = __i2c_transfer(client->adapter, msg, 1);
Antti Palosaaric0adca72011-07-08 23:34:09 -030047 if (ret == 1) {
48 ret = 0;
49 } else {
Antti Palosaari7cc39322014-12-08 23:32:19 -030050 dev_warn(&client->dev, "i2c wr failed=%d reg=%02x len=%d\n",
Antti Palosaari947debb2014-12-09 02:31:53 -030051 ret, reg, len);
Antti Palosaaric0adca72011-07-08 23:34:09 -030052 ret = -EREMOTEIO;
53 }
Antti Palosaari947debb2014-12-09 02:31:53 -030054
Antti Palosaaric0adca72011-07-08 23:34:09 -030055 return ret;
56}
57
Antti Palosaari0485a702011-08-04 20:27:19 -030058/* read multiple hardware registers */
Antti Palosaari1f153c42014-12-08 22:47:21 -030059static int rtl2830_rd(struct i2c_client *client, u8 reg, u8 *val, int len)
Antti Palosaaric0adca72011-07-08 23:34:09 -030060{
61 int ret;
Antti Palosaaric0adca72011-07-08 23:34:09 -030062 struct i2c_msg msg[2] = {
63 {
Antti Palosaarib8cb50d22014-12-09 00:24:13 -030064 .addr = client->addr,
Antti Palosaaric0adca72011-07-08 23:34:09 -030065 .flags = 0,
Antti Palosaari0485a702011-08-04 20:27:19 -030066 .len = 1,
67 .buf = &reg,
Antti Palosaaric0adca72011-07-08 23:34:09 -030068 }, {
Antti Palosaarib8cb50d22014-12-09 00:24:13 -030069 .addr = client->addr,
Antti Palosaaric0adca72011-07-08 23:34:09 -030070 .flags = I2C_M_RD,
71 .len = len,
72 .buf = val,
73 }
74 };
75
Antti Palosaarifd4cfa82014-12-09 16:14:41 -030076 ret = __i2c_transfer(client->adapter, msg, 2);
Antti Palosaaric0adca72011-07-08 23:34:09 -030077 if (ret == 2) {
78 ret = 0;
79 } else {
Antti Palosaari7cc39322014-12-08 23:32:19 -030080 dev_warn(&client->dev, "i2c rd failed=%d reg=%02x len=%d\n",
Antti Palosaari947debb2014-12-09 02:31:53 -030081 ret, reg, len);
Antti Palosaaric0adca72011-07-08 23:34:09 -030082 ret = -EREMOTEIO;
83 }
Antti Palosaari947debb2014-12-09 02:31:53 -030084
Antti Palosaaric0adca72011-07-08 23:34:09 -030085 return ret;
86}
87
Antti Palosaari0485a702011-08-04 20:27:19 -030088/* write multiple registers */
Antti Palosaari1f153c42014-12-08 22:47:21 -030089static int rtl2830_wr_regs(struct i2c_client *client, u16 reg, const u8 *val, int len)
Antti Palosaari0485a702011-08-04 20:27:19 -030090{
Antti Palosaari1f153c42014-12-08 22:47:21 -030091 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari0485a702011-08-04 20:27:19 -030092 int ret;
93 u8 reg2 = (reg >> 0) & 0xff;
94 u8 page = (reg >> 8) & 0xff;
95
Antti Palosaarifd4cfa82014-12-09 16:14:41 -030096 mutex_lock(&dev->i2c_mutex);
97
Antti Palosaari0485a702011-08-04 20:27:19 -030098 /* switch bank if needed */
Antti Palosaarif544f102014-12-08 22:31:28 -030099 if (page != dev->page) {
Antti Palosaari1f153c42014-12-08 22:47:21 -0300100 ret = rtl2830_wr(client, 0x00, &page, 1);
Antti Palosaari0485a702011-08-04 20:27:19 -0300101 if (ret)
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300102 goto err_mutex_unlock;
Antti Palosaari0485a702011-08-04 20:27:19 -0300103
Antti Palosaarif544f102014-12-08 22:31:28 -0300104 dev->page = page;
Antti Palosaari0485a702011-08-04 20:27:19 -0300105 }
106
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300107 ret = rtl2830_wr(client, reg2, val, len);
108
109err_mutex_unlock:
110 mutex_unlock(&dev->i2c_mutex);
111
112 return ret;
Antti Palosaari0485a702011-08-04 20:27:19 -0300113}
114
115/* read multiple registers */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300116static int rtl2830_rd_regs(struct i2c_client *client, u16 reg, u8 *val, int len)
Antti Palosaari0485a702011-08-04 20:27:19 -0300117{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300118 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari0485a702011-08-04 20:27:19 -0300119 int ret;
120 u8 reg2 = (reg >> 0) & 0xff;
121 u8 page = (reg >> 8) & 0xff;
122
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300123 mutex_lock(&dev->i2c_mutex);
124
Antti Palosaari0485a702011-08-04 20:27:19 -0300125 /* switch bank if needed */
Antti Palosaarif544f102014-12-08 22:31:28 -0300126 if (page != dev->page) {
Antti Palosaari1f153c42014-12-08 22:47:21 -0300127 ret = rtl2830_wr(client, 0x00, &page, 1);
Antti Palosaari0485a702011-08-04 20:27:19 -0300128 if (ret)
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300129 goto err_mutex_unlock;
Antti Palosaari0485a702011-08-04 20:27:19 -0300130
Antti Palosaarif544f102014-12-08 22:31:28 -0300131 dev->page = page;
Antti Palosaari0485a702011-08-04 20:27:19 -0300132 }
133
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300134 ret = rtl2830_rd(client, reg2, val, len);
135
136err_mutex_unlock:
137 mutex_unlock(&dev->i2c_mutex);
138
139 return ret;
Antti Palosaari0485a702011-08-04 20:27:19 -0300140}
141
Antti Palosaaric0adca72011-07-08 23:34:09 -0300142/* read single register */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300143static int rtl2830_rd_reg(struct i2c_client *client, u16 reg, u8 *val)
Antti Palosaaric0adca72011-07-08 23:34:09 -0300144{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300145 return rtl2830_rd_regs(client, reg, val, 1);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300146}
147
148/* write single register with mask */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300149static int rtl2830_wr_reg_mask(struct i2c_client *client, u16 reg, u8 val, u8 mask)
Antti Palosaaric0adca72011-07-08 23:34:09 -0300150{
151 int ret;
152 u8 tmp;
153
154 /* no need for read if whole reg is written */
155 if (mask != 0xff) {
Antti Palosaari1f153c42014-12-08 22:47:21 -0300156 ret = rtl2830_rd_regs(client, reg, &tmp, 1);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300157 if (ret)
158 return ret;
159
160 val &= mask;
161 tmp &= ~mask;
162 val |= tmp;
163 }
164
Antti Palosaari1f153c42014-12-08 22:47:21 -0300165 return rtl2830_wr_regs(client, reg, &val, 1);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300166}
167
168/* read single register with mask */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300169static int rtl2830_rd_reg_mask(struct i2c_client *client, u16 reg, u8 *val, u8 mask)
Antti Palosaaric0adca72011-07-08 23:34:09 -0300170{
171 int ret, i;
172 u8 tmp;
173
Antti Palosaari1f153c42014-12-08 22:47:21 -0300174 ret = rtl2830_rd_regs(client, reg, &tmp, 1);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300175 if (ret)
176 return ret;
177
178 tmp &= mask;
179
180 /* find position of the first bit */
181 for (i = 0; i < 8; i++) {
182 if ((mask >> i) & 0x01)
183 break;
184 }
185 *val = tmp >> i;
186
187 return 0;
188}
189
190static int rtl2830_init(struct dvb_frontend *fe)
191{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300192 struct i2c_client *client = fe->demodulator_priv;
193 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300194 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
Antti Palosaaric0adca72011-07-08 23:34:09 -0300195 int ret, i;
Antti Palosaaric0adca72011-07-08 23:34:09 -0300196 struct rtl2830_reg_val_mask tab[] = {
Antti Palosaari947debb2014-12-09 02:31:53 -0300197 {0x00d, 0x01, 0x03},
198 {0x00d, 0x10, 0x10},
199 {0x104, 0x00, 0x1e},
200 {0x105, 0x80, 0x80},
201 {0x110, 0x02, 0x03},
202 {0x110, 0x08, 0x0c},
203 {0x17b, 0x00, 0x40},
204 {0x17d, 0x05, 0x0f},
205 {0x17d, 0x50, 0xf0},
206 {0x18c, 0x08, 0x0f},
207 {0x18d, 0x00, 0xc0},
208 {0x188, 0x05, 0x0f},
209 {0x189, 0x00, 0xfc},
210 {0x2d5, 0x02, 0x02},
211 {0x2f1, 0x02, 0x06},
212 {0x2f1, 0x20, 0xf8},
213 {0x16d, 0x00, 0x01},
214 {0x1a6, 0x00, 0x80},
215 {0x106, dev->pdata->vtop, 0x3f},
216 {0x107, dev->pdata->krf, 0x3f},
217 {0x112, 0x28, 0xff},
218 {0x103, dev->pdata->agc_targ_val, 0xff},
219 {0x00a, 0x02, 0x07},
220 {0x140, 0x0c, 0x3c},
221 {0x140, 0x40, 0xc0},
222 {0x15b, 0x05, 0x07},
223 {0x15b, 0x28, 0x38},
224 {0x15c, 0x05, 0x07},
225 {0x15c, 0x28, 0x38},
226 {0x115, dev->pdata->spec_inv, 0x01},
227 {0x16f, 0x01, 0x07},
228 {0x170, 0x18, 0x38},
229 {0x172, 0x0f, 0x0f},
230 {0x173, 0x08, 0x38},
231 {0x175, 0x01, 0x07},
232 {0x176, 0x00, 0xc0},
Antti Palosaaric0adca72011-07-08 23:34:09 -0300233 };
234
235 for (i = 0; i < ARRAY_SIZE(tab); i++) {
Antti Palosaari1f153c42014-12-08 22:47:21 -0300236 ret = rtl2830_wr_reg_mask(client, tab[i].reg, tab[i].val,
Antti Palosaari947debb2014-12-09 02:31:53 -0300237 tab[i].mask);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300238 if (ret)
239 goto err;
240 }
241
Antti Palosaari1f153c42014-12-08 22:47:21 -0300242 ret = rtl2830_wr_regs(client, 0x18f, "\x28\x00", 2);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300243 if (ret)
244 goto err;
245
Antti Palosaari1f153c42014-12-08 22:47:21 -0300246 ret = rtl2830_wr_regs(client, 0x195,
Antti Palosaari947debb2014-12-09 02:31:53 -0300247 "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300248 if (ret)
249 goto err;
250
Antti Palosaaric0adca72011-07-08 23:34:09 -0300251 /* TODO: spec init */
252
253 /* soft reset */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300254 ret = rtl2830_wr_reg_mask(client, 0x101, 0x04, 0x04);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300255 if (ret)
256 goto err;
257
Antti Palosaari1f153c42014-12-08 22:47:21 -0300258 ret = rtl2830_wr_reg_mask(client, 0x101, 0x00, 0x04);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300259 if (ret)
260 goto err;
261
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300262 /* init stats here in order signal app which stats are supported */
Antti Palosaari871f7022014-12-09 08:49:44 -0300263 c->strength.len = 1;
264 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300265 c->cnr.len = 1;
266 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari5bb11ca2014-12-09 09:45:16 -0300267 c->post_bit_error.len = 1;
268 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
269 c->post_bit_count.len = 1;
270 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300271 /* start statistics polling */
272 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
273
Antti Palosaarif544f102014-12-08 22:31:28 -0300274 dev->sleeping = false;
Antti Palosaaria8567cf2012-01-21 22:40:58 -0300275
Antti Palosaaric0adca72011-07-08 23:34:09 -0300276 return ret;
277err:
Antti Palosaari7cc39322014-12-08 23:32:19 -0300278 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300279 return ret;
280}
281
Antti Palosaaria8567cf2012-01-21 22:40:58 -0300282static int rtl2830_sleep(struct dvb_frontend *fe)
283{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300284 struct i2c_client *client = fe->demodulator_priv;
285 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari947debb2014-12-09 02:31:53 -0300286
Antti Palosaarif544f102014-12-08 22:31:28 -0300287 dev->sleeping = true;
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300288 /* stop statistics polling */
289 cancel_delayed_work_sync(&dev->stat_work);
290 dev->fe_status = 0;
Antti Palosaari947debb2014-12-09 02:31:53 -0300291
Antti Palosaaria8567cf2012-01-21 22:40:58 -0300292 return 0;
293}
294
Mauro Carvalho Chehaba17ff2e2012-10-27 11:24:08 -0300295static int rtl2830_get_tune_settings(struct dvb_frontend *fe,
Antti Palosaari947debb2014-12-09 02:31:53 -0300296 struct dvb_frontend_tune_settings *s)
Antti Palosaaric0adca72011-07-08 23:34:09 -0300297{
298 s->min_delay_ms = 500;
299 s->step_size = fe->ops.info.frequency_stepsize * 2;
300 s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
301
302 return 0;
303}
304
305static int rtl2830_set_frontend(struct dvb_frontend *fe)
306{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300307 struct i2c_client *client = fe->demodulator_priv;
308 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300309 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
310 int ret, i;
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300311 u64 num;
312 u8 buf[3], tmp;
313 u32 if_ctl, if_frequency;
Antti Palosaari3a2fca22012-09-12 20:23:49 -0300314 static const u8 bw_params1[3][34] = {
Antti Palosaaric0adca72011-07-08 23:34:09 -0300315 {
316 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41,
317 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a,
318 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82,
319 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */
320 }, {
321 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca,
322 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca,
323 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e,
324 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */
325 }, {
326 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0,
327 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a,
328 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f,
329 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */
330 },
331 };
Antti Palosaari3a2fca22012-09-12 20:23:49 -0300332 static const u8 bw_params2[3][6] = {
333 {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30}, /* 6 MHz */
334 {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98}, /* 7 MHz */
335 {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64}, /* 8 MHz */
Antti Palosaaric0adca72011-07-08 23:34:09 -0300336 };
337
Antti Palosaari7cc39322014-12-08 23:32:19 -0300338 dev_dbg(&client->dev, "frequency=%u bandwidth_hz=%u inversion=%u\n",
Antti Palosaari947debb2014-12-09 02:31:53 -0300339 c->frequency, c->bandwidth_hz, c->inversion);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300340
341 /* program tuner */
342 if (fe->ops.tuner_ops.set_params)
343 fe->ops.tuner_ops.set_params(fe);
344
345 switch (c->bandwidth_hz) {
346 case 6000000:
347 i = 0;
348 break;
349 case 7000000:
350 i = 1;
351 break;
352 case 8000000:
353 i = 2;
354 break;
355 default:
Antti Palosaari7cc39322014-12-08 23:32:19 -0300356 dev_err(&client->dev, "invalid bandwidth_hz %u\n",
Antti Palosaari947debb2014-12-09 02:31:53 -0300357 c->bandwidth_hz);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300358 return -EINVAL;
359 }
360
Antti Palosaari1f153c42014-12-08 22:47:21 -0300361 ret = rtl2830_wr_reg_mask(client, 0x008, i << 1, 0x06);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300362 if (ret)
363 goto err;
364
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300365 /* program if frequency */
366 if (fe->ops.tuner_ops.get_if_frequency)
367 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
368 else
369 ret = -EINVAL;
Antti Palosaari947debb2014-12-09 02:31:53 -0300370 if (ret)
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300371 goto err;
372
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300373 num = if_frequency % dev->pdata->clk;
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300374 num *= 0x400000;
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300375 num = div_u64(num, dev->pdata->clk);
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300376 num = -num;
377 if_ctl = num & 0x3fffff;
Antti Palosaari7cc39322014-12-08 23:32:19 -0300378 dev_dbg(&client->dev, "if_frequency=%d if_ctl=%08x\n",
Antti Palosaari947debb2014-12-09 02:31:53 -0300379 if_frequency, if_ctl);
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300380
Antti Palosaari1f153c42014-12-08 22:47:21 -0300381 ret = rtl2830_rd_reg_mask(client, 0x119, &tmp, 0xc0); /* b[7:6] */
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300382 if (ret)
383 goto err;
384
385 buf[0] = tmp << 6;
386 buf[0] |= (if_ctl >> 16) & 0x3f;
387 buf[1] = (if_ctl >> 8) & 0xff;
388 buf[2] = (if_ctl >> 0) & 0xff;
389
Antti Palosaari1f153c42014-12-08 22:47:21 -0300390 ret = rtl2830_wr_regs(client, 0x119, buf, 3);
Antti Palosaari66b3c4d2012-09-12 20:23:48 -0300391 if (ret)
392 goto err;
393
Antti Palosaaric0adca72011-07-08 23:34:09 -0300394 /* 1/2 split I2C write */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300395 ret = rtl2830_wr_regs(client, 0x11c, &bw_params1[i][0], 17);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300396 if (ret)
397 goto err;
398
399 /* 2/2 split I2C write */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300400 ret = rtl2830_wr_regs(client, 0x12d, &bw_params1[i][17], 17);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300401 if (ret)
402 goto err;
403
Antti Palosaari1f153c42014-12-08 22:47:21 -0300404 ret = rtl2830_wr_regs(client, 0x19d, bw_params2[i], 6);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300405 if (ret)
406 goto err;
407
408 return ret;
409err:
Antti Palosaari7cc39322014-12-08 23:32:19 -0300410 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300411 return ret;
412}
413
Antti Palosaari631a2b62012-05-18 15:58:57 -0300414static int rtl2830_get_frontend(struct dvb_frontend *fe)
415{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300416 struct i2c_client *client = fe->demodulator_priv;
417 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari631a2b62012-05-18 15:58:57 -0300418 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
419 int ret;
420 u8 buf[3];
421
Antti Palosaarif544f102014-12-08 22:31:28 -0300422 if (dev->sleeping)
Antti Palosaaric1886372012-05-18 16:02:55 -0300423 return 0;
424
Antti Palosaari1f153c42014-12-08 22:47:21 -0300425 ret = rtl2830_rd_regs(client, 0x33c, buf, 2);
Antti Palosaari631a2b62012-05-18 15:58:57 -0300426 if (ret)
427 goto err;
428
Antti Palosaari1f153c42014-12-08 22:47:21 -0300429 ret = rtl2830_rd_reg(client, 0x351, &buf[2]);
Antti Palosaari631a2b62012-05-18 15:58:57 -0300430 if (ret)
431 goto err;
432
Antti Palosaari7cc39322014-12-08 23:32:19 -0300433 dev_dbg(&client->dev, "TPS=%*ph\n", 3, buf);
Antti Palosaari631a2b62012-05-18 15:58:57 -0300434
435 switch ((buf[0] >> 2) & 3) {
436 case 0:
437 c->modulation = QPSK;
438 break;
439 case 1:
440 c->modulation = QAM_16;
441 break;
442 case 2:
443 c->modulation = QAM_64;
444 break;
445 }
446
447 switch ((buf[2] >> 2) & 1) {
448 case 0:
449 c->transmission_mode = TRANSMISSION_MODE_2K;
450 break;
451 case 1:
452 c->transmission_mode = TRANSMISSION_MODE_8K;
453 }
454
455 switch ((buf[2] >> 0) & 3) {
456 case 0:
457 c->guard_interval = GUARD_INTERVAL_1_32;
458 break;
459 case 1:
460 c->guard_interval = GUARD_INTERVAL_1_16;
461 break;
462 case 2:
463 c->guard_interval = GUARD_INTERVAL_1_8;
464 break;
465 case 3:
466 c->guard_interval = GUARD_INTERVAL_1_4;
467 break;
468 }
469
470 switch ((buf[0] >> 4) & 7) {
471 case 0:
472 c->hierarchy = HIERARCHY_NONE;
473 break;
474 case 1:
475 c->hierarchy = HIERARCHY_1;
476 break;
477 case 2:
478 c->hierarchy = HIERARCHY_2;
479 break;
480 case 3:
481 c->hierarchy = HIERARCHY_4;
482 break;
483 }
484
485 switch ((buf[1] >> 3) & 7) {
486 case 0:
487 c->code_rate_HP = FEC_1_2;
488 break;
489 case 1:
490 c->code_rate_HP = FEC_2_3;
491 break;
492 case 2:
493 c->code_rate_HP = FEC_3_4;
494 break;
495 case 3:
496 c->code_rate_HP = FEC_5_6;
497 break;
498 case 4:
499 c->code_rate_HP = FEC_7_8;
500 break;
501 }
502
503 switch ((buf[1] >> 0) & 7) {
504 case 0:
505 c->code_rate_LP = FEC_1_2;
506 break;
507 case 1:
508 c->code_rate_LP = FEC_2_3;
509 break;
510 case 2:
511 c->code_rate_LP = FEC_3_4;
512 break;
513 case 3:
514 c->code_rate_LP = FEC_5_6;
515 break;
516 case 4:
517 c->code_rate_LP = FEC_7_8;
518 break;
519 }
520
521 return 0;
522err:
Antti Palosaari7cc39322014-12-08 23:32:19 -0300523 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari631a2b62012-05-18 15:58:57 -0300524 return ret;
525}
526
Antti Palosaaric0adca72011-07-08 23:34:09 -0300527static int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status)
528{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300529 struct i2c_client *client = fe->demodulator_priv;
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300530 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300531 int ret;
532 u8 tmp;
Antti Palosaari947debb2014-12-09 02:31:53 -0300533
Antti Palosaaric0adca72011-07-08 23:34:09 -0300534 *status = 0;
535
Antti Palosaarif544f102014-12-08 22:31:28 -0300536 if (dev->sleeping)
Antti Palosaaria8567cf2012-01-21 22:40:58 -0300537 return 0;
538
Antti Palosaari1f153c42014-12-08 22:47:21 -0300539 ret = rtl2830_rd_reg_mask(client, 0x351, &tmp, 0x78); /* [6:3] */
Antti Palosaaric0adca72011-07-08 23:34:09 -0300540 if (ret)
541 goto err;
542
543 if (tmp == 11) {
544 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
545 FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
546 } else if (tmp == 10) {
547 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
548 FE_HAS_VITERBI;
549 }
550
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300551 dev->fe_status = *status;
552
Antti Palosaaric0adca72011-07-08 23:34:09 -0300553 return ret;
554err:
Antti Palosaari7cc39322014-12-08 23:32:19 -0300555 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaaric0adca72011-07-08 23:34:09 -0300556 return ret;
557}
558
559static int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr)
560{
Antti Palosaari6dcfe3c2014-12-09 10:48:10 -0300561 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Antti Palosaarieba672a2012-05-15 18:32:33 -0300562
Antti Palosaari6dcfe3c2014-12-09 10:48:10 -0300563 if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
564 *snr = div_s64(c->cnr.stat[0].svalue, 100);
Antti Palosaarieba672a2012-05-15 18:32:33 -0300565 else
566 *snr = 0;
567
Antti Palosaaric0adca72011-07-08 23:34:09 -0300568 return 0;
569}
570
571static int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber)
572{
Antti Palosaari1f153c42014-12-08 22:47:21 -0300573 struct i2c_client *client = fe->demodulator_priv;
574 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari525ffc12012-05-18 12:23:42 -0300575
Antti Palosaarif4913912014-12-09 10:27:32 -0300576 *ber = (dev->post_bit_error - dev->post_bit_error_prev);
577 dev->post_bit_error_prev = dev->post_bit_error;
Antti Palosaari525ffc12012-05-18 12:23:42 -0300578
Antti Palosaaric0adca72011-07-08 23:34:09 -0300579 return 0;
580}
581
582static int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
583{
584 *ucblocks = 0;
Antti Palosaari947debb2014-12-09 02:31:53 -0300585
Antti Palosaaric0adca72011-07-08 23:34:09 -0300586 return 0;
587}
588
589static int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
590{
Antti Palosaarid512e2862014-12-09 10:20:01 -0300591 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Antti Palosaari78e75072012-05-18 15:17:51 -0300592
Antti Palosaarid512e2862014-12-09 10:20:01 -0300593 if (c->strength.stat[0].scale == FE_SCALE_RELATIVE)
594 *strength = c->strength.stat[0].uvalue;
Antti Palosaari78e75072012-05-18 15:17:51 -0300595 else
Antti Palosaarid512e2862014-12-09 10:20:01 -0300596 *strength = 0;
Antti Palosaari78e75072012-05-18 15:17:51 -0300597
Antti Palosaaric0adca72011-07-08 23:34:09 -0300598 return 0;
599}
600
Antti Palosaaric0adca72011-07-08 23:34:09 -0300601static struct dvb_frontend_ops rtl2830_ops = {
Antti Palosaari947debb2014-12-09 02:31:53 -0300602 .delsys = {SYS_DVBT},
Antti Palosaaric0adca72011-07-08 23:34:09 -0300603 .info = {
604 .name = "Realtek RTL2830 (DVB-T)",
605 .caps = FE_CAN_FEC_1_2 |
606 FE_CAN_FEC_2_3 |
607 FE_CAN_FEC_3_4 |
608 FE_CAN_FEC_5_6 |
609 FE_CAN_FEC_7_8 |
610 FE_CAN_FEC_AUTO |
611 FE_CAN_QPSK |
612 FE_CAN_QAM_16 |
613 FE_CAN_QAM_64 |
614 FE_CAN_QAM_AUTO |
615 FE_CAN_TRANSMISSION_MODE_AUTO |
616 FE_CAN_GUARD_INTERVAL_AUTO |
617 FE_CAN_HIERARCHY_AUTO |
618 FE_CAN_RECOVER |
619 FE_CAN_MUTE_TS
620 },
621
Antti Palosaaric0adca72011-07-08 23:34:09 -0300622 .init = rtl2830_init,
Antti Palosaaria8567cf2012-01-21 22:40:58 -0300623 .sleep = rtl2830_sleep,
Antti Palosaaric0adca72011-07-08 23:34:09 -0300624
625 .get_tune_settings = rtl2830_get_tune_settings,
626
627 .set_frontend = rtl2830_set_frontend,
Antti Palosaari631a2b62012-05-18 15:58:57 -0300628 .get_frontend = rtl2830_get_frontend,
Antti Palosaaric0adca72011-07-08 23:34:09 -0300629
630 .read_status = rtl2830_read_status,
631 .read_snr = rtl2830_read_snr,
632 .read_ber = rtl2830_read_ber,
633 .read_ucblocks = rtl2830_read_ucblocks,
634 .read_signal_strength = rtl2830_read_signal_strength,
635};
636
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300637static void rtl2830_stat_work(struct work_struct *work)
638{
639 struct rtl2830_dev *dev = container_of(work, struct rtl2830_dev, stat_work.work);
640 struct i2c_client *client = dev->client;
641 struct dtv_frontend_properties *c = &dev->fe.dtv_property_cache;
642 int ret, tmp;
643 u8 u8tmp, buf[2];
644 u16 u16tmp;
645
646 dev_dbg(&client->dev, "\n");
647
Antti Palosaari871f7022014-12-09 08:49:44 -0300648 /* signal strength */
649 if (dev->fe_status & FE_HAS_SIGNAL) {
650 struct {signed int x:14; } s;
651
652 /* read IF AGC */
653 ret = rtl2830_rd_regs(client, 0x359, buf, 2);
654 if (ret)
655 goto err;
656
657 u16tmp = buf[0] << 8 | buf[1] << 0;
658 u16tmp &= 0x3fff; /* [13:0] */
659 tmp = s.x = u16tmp; /* 14-bit bin to 2 complement */
660 u16tmp = clamp_val(-4 * tmp + 32767, 0x0000, 0xffff);
661
662 dev_dbg(&client->dev, "IF AGC=%d\n", tmp);
663
664 c->strength.stat[0].scale = FE_SCALE_RELATIVE;
665 c->strength.stat[0].uvalue = u16tmp;
666 } else {
667 c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
668 }
669
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300670 /* CNR */
671 if (dev->fe_status & FE_HAS_VITERBI) {
672 unsigned hierarchy, constellation;
673 #define CONSTELLATION_NUM 3
674 #define HIERARCHY_NUM 4
675 static const u32 constant[CONSTELLATION_NUM][HIERARCHY_NUM] = {
676 {70705899, 70705899, 70705899, 70705899},
677 {82433173, 82433173, 87483115, 94445660},
678 {92888734, 92888734, 95487525, 99770748},
679 };
680
681 ret = rtl2830_rd_reg(client, 0x33c, &u8tmp);
682 if (ret)
683 goto err;
684
685 constellation = (u8tmp >> 2) & 0x03; /* [3:2] */
686 if (constellation > CONSTELLATION_NUM - 1)
687 goto err_schedule_delayed_work;
688
689 hierarchy = (u8tmp >> 4) & 0x07; /* [6:4] */
690 if (hierarchy > HIERARCHY_NUM - 1)
691 goto err_schedule_delayed_work;
692
693 ret = rtl2830_rd_regs(client, 0x40c, buf, 2);
694 if (ret)
695 goto err;
696
697 u16tmp = buf[0] << 8 | buf[1] << 0;
698 if (u16tmp)
699 tmp = (constant[constellation][hierarchy] -
700 intlog10(u16tmp)) / ((1 << 24) / 10000);
701 else
702 tmp = 0;
703
704 dev_dbg(&client->dev, "CNR raw=%u\n", u16tmp);
705
706 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
707 c->cnr.stat[0].svalue = tmp;
708 } else {
709 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
710 }
711
Antti Palosaari5bb11ca2014-12-09 09:45:16 -0300712 /* BER */
713 if (dev->fe_status & FE_HAS_LOCK) {
714 ret = rtl2830_rd_regs(client, 0x34e, buf, 2);
715 if (ret)
716 goto err;
717
718 u16tmp = buf[0] << 8 | buf[1] << 0;
719 dev->post_bit_error += u16tmp;
720 dev->post_bit_count += 1000000;
721
722 dev_dbg(&client->dev, "BER errors=%u total=1000000\n", u16tmp);
723
724 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
725 c->post_bit_error.stat[0].uvalue = dev->post_bit_error;
726 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
727 c->post_bit_count.stat[0].uvalue = dev->post_bit_count;
728 } else {
729 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
730 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
731 }
732
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300733err_schedule_delayed_work:
734 schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
735 return;
736err:
737 dev_dbg(&client->dev, "failed=%d\n", ret);
738}
739
Antti Palosaaridf70dda2014-12-09 16:08:44 -0300740static int rtl2830_pid_filter_ctrl(struct dvb_frontend *fe, int onoff)
741{
742 struct i2c_client *client = fe->demodulator_priv;
743 int ret;
744 u8 u8tmp;
745
746 dev_dbg(&client->dev, "onoff=%d\n", onoff);
747
748 /* enable / disable PID filter */
749 if (onoff)
750 u8tmp = 0x80;
751 else
752 u8tmp = 0x00;
753
754 ret = rtl2830_wr_reg_mask(client, 0x061, u8tmp, 0x80);
755 if (ret)
756 goto err;
757
758 return 0;
759err:
760 dev_dbg(&client->dev, "failed=%d\n", ret);
761 return ret;
762}
763
764static int rtl2830_pid_filter(struct dvb_frontend *fe, u8 index, u16 pid, int onoff)
765{
766 struct i2c_client *client = fe->demodulator_priv;
767 struct rtl2830_dev *dev = i2c_get_clientdata(client);
768 int ret;
769 u8 buf[4];
770
771 dev_dbg(&client->dev, "index=%d pid=%04x onoff=%d\n",
772 index, pid, onoff);
773
774 /* skip invalid PIDs (0x2000) */
775 if (pid > 0x1fff || index > 32)
776 return 0;
777
778 if (onoff)
779 set_bit(index, &dev->filters);
780 else
781 clear_bit(index, &dev->filters);
782
783 /* enable / disable PIDs */
784 buf[0] = (dev->filters >> 0) & 0xff;
785 buf[1] = (dev->filters >> 8) & 0xff;
786 buf[2] = (dev->filters >> 16) & 0xff;
787 buf[3] = (dev->filters >> 24) & 0xff;
788 ret = rtl2830_wr_regs(client, 0x062, buf, 4);
789 if (ret)
790 goto err;
791
792 /* add PID */
793 buf[0] = (pid >> 8) & 0xff;
794 buf[1] = (pid >> 0) & 0xff;
795 ret = rtl2830_wr_regs(client, 0x066 + 2 * index, buf, 2);
796 if (ret)
797 goto err;
798
799 return 0;
800err:
801 dev_dbg(&client->dev, "failed=%d\n", ret);
802 return ret;
803}
804
Antti Palosaari28c08792014-12-07 04:07:29 -0300805/*
806 * I2C gate/repeater logic
807 * We must use unlocked i2c_transfer() here because I2C lock is already taken
808 * by tuner driver. Gate is closed automatically after single I2C xfer.
809 */
810static int rtl2830_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
811{
812 struct i2c_client *client = mux_priv;
Antti Palosaarif544f102014-12-08 22:31:28 -0300813 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari28c08792014-12-07 04:07:29 -0300814 struct i2c_msg select_reg_page_msg[1] = {
815 {
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300816 .addr = client->addr,
Antti Palosaari28c08792014-12-07 04:07:29 -0300817 .flags = 0,
818 .len = 2,
819 .buf = "\x00\x01",
820 }
821 };
822 struct i2c_msg gate_open_msg[1] = {
823 {
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300824 .addr = client->addr,
Antti Palosaari28c08792014-12-07 04:07:29 -0300825 .flags = 0,
826 .len = 2,
827 .buf = "\x01\x08",
828 }
829 };
830 int ret;
831
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300832 dev_dbg(&client->dev, "\n");
833
834 mutex_lock(&dev->i2c_mutex);
835
Antti Palosaari28c08792014-12-07 04:07:29 -0300836 /* select register page */
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300837 ret = __i2c_transfer(client->adapter, select_reg_page_msg, 1);
Antti Palosaari28c08792014-12-07 04:07:29 -0300838 if (ret != 1) {
839 dev_warn(&client->dev, "i2c write failed %d\n", ret);
840 if (ret >= 0)
841 ret = -EREMOTEIO;
842 goto err;
843 }
844
Antti Palosaarif544f102014-12-08 22:31:28 -0300845 dev->page = 1;
Antti Palosaari28c08792014-12-07 04:07:29 -0300846
847 /* open tuner I2C repeater for 1 xfer, closes automatically */
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300848 ret = __i2c_transfer(client->adapter, gate_open_msg, 1);
Antti Palosaari28c08792014-12-07 04:07:29 -0300849 if (ret != 1) {
850 dev_warn(&client->dev, "i2c write failed %d\n", ret);
851 if (ret >= 0)
852 ret = -EREMOTEIO;
853 goto err;
854 }
855
856 return 0;
Antti Palosaari28c08792014-12-07 04:07:29 -0300857err:
Antti Palosaari7cc39322014-12-08 23:32:19 -0300858 dev_dbg(&client->dev, "failed=%d\n", ret);
Antti Palosaari28c08792014-12-07 04:07:29 -0300859 return ret;
860}
861
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300862static int rtl2830_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
863{
864 struct i2c_client *client = mux_priv;
865 struct rtl2830_dev *dev = i2c_get_clientdata(client);
866
867 dev_dbg(&client->dev, "\n");
868
869 mutex_unlock(&dev->i2c_mutex);
870
871 return 0;
872}
873
Antti Palosaari28c08792014-12-07 04:07:29 -0300874static struct dvb_frontend *rtl2830_get_dvb_frontend(struct i2c_client *client)
875{
Antti Palosaarif544f102014-12-08 22:31:28 -0300876 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari28c08792014-12-07 04:07:29 -0300877
878 dev_dbg(&client->dev, "\n");
879
Antti Palosaarif544f102014-12-08 22:31:28 -0300880 return &dev->fe;
Antti Palosaari28c08792014-12-07 04:07:29 -0300881}
882
883static struct i2c_adapter *rtl2830_get_i2c_adapter(struct i2c_client *client)
884{
Antti Palosaarif544f102014-12-08 22:31:28 -0300885 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari28c08792014-12-07 04:07:29 -0300886
887 dev_dbg(&client->dev, "\n");
888
Antti Palosaarif544f102014-12-08 22:31:28 -0300889 return dev->adapter;
Antti Palosaari28c08792014-12-07 04:07:29 -0300890}
891
892static int rtl2830_probe(struct i2c_client *client,
Antti Palosaari947debb2014-12-09 02:31:53 -0300893 const struct i2c_device_id *id)
Antti Palosaari28c08792014-12-07 04:07:29 -0300894{
895 struct rtl2830_platform_data *pdata = client->dev.platform_data;
Antti Palosaarif544f102014-12-08 22:31:28 -0300896 struct rtl2830_dev *dev;
Antti Palosaari28c08792014-12-07 04:07:29 -0300897 int ret;
898 u8 u8tmp;
899
900 dev_dbg(&client->dev, "\n");
901
902 if (pdata == NULL) {
903 ret = -EINVAL;
904 goto err;
905 }
906
907 /* allocate memory for the internal state */
Antti Palosaarif544f102014-12-08 22:31:28 -0300908 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
909 if (dev == NULL) {
Antti Palosaari28c08792014-12-07 04:07:29 -0300910 ret = -ENOMEM;
911 goto err;
912 }
913
914 /* setup the state */
Antti Palosaarif544f102014-12-08 22:31:28 -0300915 i2c_set_clientdata(client, dev);
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300916 dev->client = client;
Antti Palosaarib8cb50d22014-12-09 00:24:13 -0300917 dev->pdata = client->dev.platform_data;
Antti Palosaarif544f102014-12-08 22:31:28 -0300918 dev->sleeping = true;
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300919 mutex_init(&dev->i2c_mutex);
Antti Palosaari47b4dbf2014-12-09 06:14:36 -0300920 INIT_DELAYED_WORK(&dev->stat_work, rtl2830_stat_work);
Antti Palosaari28c08792014-12-07 04:07:29 -0300921
922 /* check if the demod is there */
Antti Palosaari1f153c42014-12-08 22:47:21 -0300923 ret = rtl2830_rd_reg(client, 0x000, &u8tmp);
Antti Palosaari28c08792014-12-07 04:07:29 -0300924 if (ret)
925 goto err_kfree;
926
927 /* create muxed i2c adapter for tuner */
Antti Palosaarif544f102014-12-08 22:31:28 -0300928 dev->adapter = i2c_add_mux_adapter(client->adapter, &client->dev,
Antti Palosaarifd4cfa82014-12-09 16:14:41 -0300929 client, 0, 0, 0, rtl2830_select, rtl2830_deselect);
Antti Palosaarif544f102014-12-08 22:31:28 -0300930 if (dev->adapter == NULL) {
Antti Palosaari28c08792014-12-07 04:07:29 -0300931 ret = -ENODEV;
932 goto err_kfree;
933 }
934
935 /* create dvb frontend */
Antti Palosaarif544f102014-12-08 22:31:28 -0300936 memcpy(&dev->fe.ops, &rtl2830_ops, sizeof(dev->fe.ops));
Antti Palosaari1f153c42014-12-08 22:47:21 -0300937 dev->fe.demodulator_priv = client;
Antti Palosaari28c08792014-12-07 04:07:29 -0300938
939 /* setup callbacks */
940 pdata->get_dvb_frontend = rtl2830_get_dvb_frontend;
941 pdata->get_i2c_adapter = rtl2830_get_i2c_adapter;
Antti Palosaaridf70dda2014-12-09 16:08:44 -0300942 pdata->pid_filter = rtl2830_pid_filter;
943 pdata->pid_filter_ctrl = rtl2830_pid_filter_ctrl;
Antti Palosaari28c08792014-12-07 04:07:29 -0300944
945 dev_info(&client->dev, "Realtek RTL2830 successfully attached\n");
Antti Palosaari28c08792014-12-07 04:07:29 -0300946
Antti Palosaari947debb2014-12-09 02:31:53 -0300947 return 0;
Antti Palosaari28c08792014-12-07 04:07:29 -0300948err_kfree:
Antti Palosaarif544f102014-12-08 22:31:28 -0300949 kfree(dev);
Antti Palosaari28c08792014-12-07 04:07:29 -0300950err:
951 dev_dbg(&client->dev, "failed=%d\n", ret);
952 return ret;
953}
954
955static int rtl2830_remove(struct i2c_client *client)
956{
Antti Palosaarif544f102014-12-08 22:31:28 -0300957 struct rtl2830_dev *dev = i2c_get_clientdata(client);
Antti Palosaari28c08792014-12-07 04:07:29 -0300958
959 dev_dbg(&client->dev, "\n");
960
Antti Palosaarif544f102014-12-08 22:31:28 -0300961 i2c_del_mux_adapter(dev->adapter);
962 kfree(dev);
Antti Palosaari947debb2014-12-09 02:31:53 -0300963
Antti Palosaari28c08792014-12-07 04:07:29 -0300964 return 0;
965}
966
967static const struct i2c_device_id rtl2830_id_table[] = {
968 {"rtl2830", 0},
969 {}
970};
971MODULE_DEVICE_TABLE(i2c, rtl2830_id_table);
972
973static struct i2c_driver rtl2830_driver = {
974 .driver = {
975 .owner = THIS_MODULE,
976 .name = "rtl2830",
977 },
978 .probe = rtl2830_probe,
979 .remove = rtl2830_remove,
980 .id_table = rtl2830_id_table,
981};
982
983module_i2c_driver(rtl2830_driver);
984
Antti Palosaaric0adca72011-07-08 23:34:09 -0300985MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
986MODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver");
987MODULE_LICENSE("GPL");