2 * MaxLinear MxL301RF OFDM tuner driver
4 * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
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.
19 * This driver is incomplete and lacks init/config of the chips,
20 * as the necessary info is not disclosed.
21 * Other features like get_if_frequency() are missing as well.
22 * It assumes that users of this driver (such as a PCI bridge of
23 * DTV receiver cards) properly init and configure the chip
24 * via I2C *before* calling this driver's init() function.
26 * Currently, PT3 driver is the only one that uses this driver,
27 * and contains init/config code in its firmware.
28 * Thus some part of the code might be dependent on PT3 specific config.
31 #include <linux/kernel.h>
34 struct mxl301rf_state
{
35 struct mxl301rf_config cfg
;
36 struct i2c_client
*i2c
;
39 static struct mxl301rf_state
*cfg_to_state(struct mxl301rf_config
*c
)
41 return container_of(c
, struct mxl301rf_state
, cfg
);
44 static int raw_write(struct mxl301rf_state
*state
, const u8
*buf
, int len
)
48 ret
= i2c_master_send(state
->i2c
, buf
, len
);
49 if (ret
>= 0 && ret
< len
)
51 return (ret
== len
) ? 0 : ret
;
54 static int reg_write(struct mxl301rf_state
*state
, u8 reg
, u8 val
)
56 u8 buf
[2] = { reg
, val
};
58 return raw_write(state
, buf
, 2);
61 static int reg_read(struct mxl301rf_state
*state
, u8 reg
, u8
*val
)
63 u8 wbuf
[2] = { 0xfb, reg
};
66 ret
= raw_write(state
, wbuf
, sizeof(wbuf
));
68 ret
= i2c_master_recv(state
->i2c
, val
, 1);
69 if (ret
>= 0 && ret
< 1)
71 return (ret
== 1) ? 0 : ret
;
76 /* get RSSI and update propery cache, set to *out in % */
77 static int mxl301rf_get_rf_strength(struct dvb_frontend
*fe
, u16
*out
)
79 struct mxl301rf_state
*state
;
81 u8 rf_in1
, rf_in2
, rf_off1
, rf_off2
;
84 struct dtv_fe_stats
*rssi
;
86 rssi
= &fe
->dtv_property_cache
.strength
;
88 rssi
->stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
91 state
= fe
->tuner_priv
;
92 ret
= reg_write(state
, 0x14, 0x01);
95 usleep_range(1000, 2000);
97 ret
= reg_read(state
, 0x18, &rf_in1
);
99 ret
= reg_read(state
, 0x19, &rf_in2
);
101 ret
= reg_read(state
, 0xd6, &rf_off1
);
103 ret
= reg_read(state
, 0xd7, &rf_off2
);
107 rf_in
= (rf_in2
& 0x07) << 8 | rf_in1
;
108 rf_off
= (rf_off2
& 0x0f) << 5 | (rf_off1
>> 3);
109 level
= rf_in
- rf_off
- (113 << 3); /* x8 dBm */
110 level
= level
* 1000 / 8;
111 rssi
->stat
[0].svalue
= level
;
112 rssi
->stat
[0].scale
= FE_SCALE_DECIBEL
;
113 /* *out = (level - min) * 100 / (max - min) */
114 *out
= (rf_in
- rf_off
+ (1 << 9) - 1) * 100 / ((5 << 9) - 2);
118 /* spur shift parameters */
120 u32 freq
; /* Channel center frequency */
121 u32 ofst_th
; /* Offset frequency threshold */
122 u8 shf_val
; /* Spur shift value */
123 u8 shf_dir
; /* Spur shift direction */
126 static const struct shf shf_tab
[] = {
127 { 64500, 500, 0x92, 0x07 },
128 { 191500, 300, 0xe2, 0x07 },
129 { 205500, 500, 0x2c, 0x04 },
130 { 212500, 500, 0x1e, 0x04 },
131 { 226500, 500, 0xd4, 0x07 },
132 { 99143, 500, 0x9c, 0x07 },
133 { 173143, 500, 0xd4, 0x07 },
134 { 191143, 300, 0xd4, 0x07 },
135 { 207143, 500, 0xce, 0x07 },
136 { 225143, 500, 0xce, 0x07 },
137 { 243143, 500, 0xd4, 0x07 },
138 { 261143, 500, 0xd4, 0x07 },
139 { 291143, 500, 0xd4, 0x07 },
140 { 339143, 500, 0x2c, 0x04 },
141 { 117143, 500, 0x7a, 0x07 },
142 { 135143, 300, 0x7a, 0x07 },
143 { 153143, 500, 0x01, 0x07 }
149 } __attribute__ ((__packed__
));
151 static const struct reg_val set_idac
[] = {
162 static int mxl301rf_set_params(struct dvb_frontend
*fe
)
164 struct reg_val tune0
[] = {
165 { 0x13, 0x00 }, /* abort tuning */
168 { 0x10, 0x95 }, /* BW */
170 { 0x61, 0x00 }, /* spur shift value (placeholder) */
171 { 0x62, 0xa0 } /* spur shift direction (placeholder) */
174 struct reg_val tune1
[] = {
175 { 0x11, 0x40 }, /* RF frequency L (placeholder) */
176 { 0x12, 0x0e }, /* RF frequency H (placeholder) */
177 { 0x13, 0x01 } /* start tune */
180 struct mxl301rf_state
*state
;
186 state
= fe
->tuner_priv
;
187 freq
= fe
->dtv_property_cache
.frequency
;
189 /* spur shift function (for analog) */
190 for (i
= 0; i
< ARRAY_SIZE(shf_tab
); i
++) {
191 if (freq
>= (shf_tab
[i
].freq
- shf_tab
[i
].ofst_th
) * 1000 &&
192 freq
<= (shf_tab
[i
].freq
+ shf_tab
[i
].ofst_th
) * 1000) {
193 tune0
[5].val
= shf_tab
[i
].shf_val
;
194 tune0
[6].val
= 0xa0 | shf_tab
[i
].shf_dir
;
198 ret
= raw_write(state
, (u8
*) tune0
, sizeof(tune0
));
201 usleep_range(3000, 4000);
203 /* convert freq to 10.6 fixed point float [MHz] */
205 tmp
= freq
% 1000000;
207 for (i
= 0; i
< 6; i
++) {
217 tune1
[0].val
= f
& 0xff;
218 tune1
[1].val
= f
>> 8;
219 ret
= raw_write(state
, (u8
*) tune1
, sizeof(tune1
));
224 ret
= reg_write(state
, 0x1a, 0x0d);
227 ret
= raw_write(state
, (u8
*) set_idac
, sizeof(set_idac
));
233 dev_warn(&state
->i2c
->dev
, "(%s) failed. [adap%d-fe%d]\n",
234 __func__
, fe
->dvb
->num
, fe
->id
);
238 static const struct reg_val standby_data
[] = {
243 static int mxl301rf_sleep(struct dvb_frontend
*fe
)
245 struct mxl301rf_state
*state
;
248 state
= fe
->tuner_priv
;
249 ret
= raw_write(state
, (u8
*)standby_data
, sizeof(standby_data
));
251 dev_warn(&state
->i2c
->dev
, "(%s) failed. [adap%d-fe%d]\n",
252 __func__
, fe
->dvb
->num
, fe
->id
);
257 /* init sequence is not public.
258 * the parent must have init'ed the device.
261 static int mxl301rf_init(struct dvb_frontend
*fe
)
263 struct mxl301rf_state
*state
;
266 state
= fe
->tuner_priv
;
268 ret
= reg_write(state
, 0x01, 0x01);
270 dev_warn(&state
->i2c
->dev
, "(%s) failed. [adap%d-fe%d]\n",
271 __func__
, fe
->dvb
->num
, fe
->id
);
277 /* I2C driver functions */
279 static const struct dvb_tuner_ops mxl301rf_ops
= {
281 .name
= "MaxLinear MxL301RF",
283 .frequency_min
= 93000000,
284 .frequency_max
= 803142857,
287 .init
= mxl301rf_init
,
288 .sleep
= mxl301rf_sleep
,
290 .set_params
= mxl301rf_set_params
,
291 .get_rf_strength
= mxl301rf_get_rf_strength
,
295 static int mxl301rf_probe(struct i2c_client
*client
,
296 const struct i2c_device_id
*id
)
298 struct mxl301rf_state
*state
;
299 struct mxl301rf_config
*cfg
;
300 struct dvb_frontend
*fe
;
302 state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
307 cfg
= client
->dev
.platform_data
;
309 memcpy(&state
->cfg
, cfg
, sizeof(state
->cfg
));
311 fe
->tuner_priv
= state
;
312 memcpy(&fe
->ops
.tuner_ops
, &mxl301rf_ops
, sizeof(mxl301rf_ops
));
314 i2c_set_clientdata(client
, &state
->cfg
);
315 dev_info(&client
->dev
, "MaxLinear MxL301RF attached.\n");
319 static int mxl301rf_remove(struct i2c_client
*client
)
321 struct mxl301rf_state
*state
;
323 state
= cfg_to_state(i2c_get_clientdata(client
));
324 state
->cfg
.fe
->tuner_priv
= NULL
;
330 static const struct i2c_device_id mxl301rf_id
[] = {
334 MODULE_DEVICE_TABLE(i2c
, mxl301rf_id
);
336 static struct i2c_driver mxl301rf_driver
= {
340 .probe
= mxl301rf_probe
,
341 .remove
= mxl301rf_remove
,
342 .id_table
= mxl301rf_id
,
345 module_i2c_driver(mxl301rf_driver
);
347 MODULE_DESCRIPTION("MaxLinear MXL301RF tuner");
348 MODULE_AUTHOR("Akihiro TSUKADA");
349 MODULE_LICENSE("GPL");