1 // SPDX-License-Identifier: GPL-2.0
3 * MaxLinear MxL301RF OFDM tuner driver
5 * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com>
10 * This driver is incomplete and lacks init/config of the chips,
11 * as the necessary info is not disclosed.
12 * Other features like get_if_frequency() are missing as well.
13 * It assumes that users of this driver (such as a PCI bridge of
14 * DTV receiver cards) properly init and configure the chip
15 * via I2C *before* calling this driver's init() function.
17 * Currently, PT3 driver is the only one that uses this driver,
18 * and contains init/config code in its firmware.
19 * Thus some part of the code might be dependent on PT3 specific config.
22 #include <linux/kernel.h>
25 struct mxl301rf_state
{
26 struct mxl301rf_config cfg
;
27 struct i2c_client
*i2c
;
30 static struct mxl301rf_state
*cfg_to_state(struct mxl301rf_config
*c
)
32 return container_of(c
, struct mxl301rf_state
, cfg
);
35 static int raw_write(struct mxl301rf_state
*state
, const u8
*buf
, int len
)
39 ret
= i2c_master_send(state
->i2c
, buf
, len
);
40 if (ret
>= 0 && ret
< len
)
42 return (ret
== len
) ? 0 : ret
;
45 static int reg_write(struct mxl301rf_state
*state
, u8 reg
, u8 val
)
47 u8 buf
[2] = { reg
, val
};
49 return raw_write(state
, buf
, 2);
52 static int reg_read(struct mxl301rf_state
*state
, u8 reg
, u8
*val
)
54 u8 wbuf
[2] = { 0xfb, reg
};
57 ret
= raw_write(state
, wbuf
, sizeof(wbuf
));
59 ret
= i2c_master_recv(state
->i2c
, val
, 1);
60 if (ret
>= 0 && ret
< 1)
62 return (ret
== 1) ? 0 : ret
;
67 /* get RSSI and update propery cache, set to *out in % */
68 static int mxl301rf_get_rf_strength(struct dvb_frontend
*fe
, u16
*out
)
70 struct mxl301rf_state
*state
;
72 u8 rf_in1
, rf_in2
, rf_off1
, rf_off2
;
75 struct dtv_fe_stats
*rssi
;
77 rssi
= &fe
->dtv_property_cache
.strength
;
79 rssi
->stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
82 state
= fe
->tuner_priv
;
83 ret
= reg_write(state
, 0x14, 0x01);
86 usleep_range(1000, 2000);
88 ret
= reg_read(state
, 0x18, &rf_in1
);
90 ret
= reg_read(state
, 0x19, &rf_in2
);
92 ret
= reg_read(state
, 0xd6, &rf_off1
);
94 ret
= reg_read(state
, 0xd7, &rf_off2
);
98 rf_in
= (rf_in2
& 0x07) << 8 | rf_in1
;
99 rf_off
= (rf_off2
& 0x0f) << 5 | (rf_off1
>> 3);
100 level
= rf_in
- rf_off
- (113 << 3); /* x8 dBm */
101 level
= level
* 1000 / 8;
102 rssi
->stat
[0].svalue
= level
;
103 rssi
->stat
[0].scale
= FE_SCALE_DECIBEL
;
104 /* *out = (level - min) * 100 / (max - min) */
105 *out
= (rf_in
- rf_off
+ (1 << 9) - 1) * 100 / ((5 << 9) - 2);
109 /* spur shift parameters */
111 u32 freq
; /* Channel center frequency */
112 u32 ofst_th
; /* Offset frequency threshold */
113 u8 shf_val
; /* Spur shift value */
114 u8 shf_dir
; /* Spur shift direction */
117 static const struct shf shf_tab
[] = {
118 { 64500, 500, 0x92, 0x07 },
119 { 191500, 300, 0xe2, 0x07 },
120 { 205500, 500, 0x2c, 0x04 },
121 { 212500, 500, 0x1e, 0x04 },
122 { 226500, 500, 0xd4, 0x07 },
123 { 99143, 500, 0x9c, 0x07 },
124 { 173143, 500, 0xd4, 0x07 },
125 { 191143, 300, 0xd4, 0x07 },
126 { 207143, 500, 0xce, 0x07 },
127 { 225143, 500, 0xce, 0x07 },
128 { 243143, 500, 0xd4, 0x07 },
129 { 261143, 500, 0xd4, 0x07 },
130 { 291143, 500, 0xd4, 0x07 },
131 { 339143, 500, 0x2c, 0x04 },
132 { 117143, 500, 0x7a, 0x07 },
133 { 135143, 300, 0x7a, 0x07 },
134 { 153143, 500, 0x01, 0x07 }
140 } __attribute__ ((__packed__
));
142 static const struct reg_val set_idac
[] = {
153 static int mxl301rf_set_params(struct dvb_frontend
*fe
)
155 struct reg_val tune0
[] = {
156 { 0x13, 0x00 }, /* abort tuning */
159 { 0x10, 0x95 }, /* BW */
161 { 0x61, 0x00 }, /* spur shift value (placeholder) */
162 { 0x62, 0xa0 } /* spur shift direction (placeholder) */
165 struct reg_val tune1
[] = {
166 { 0x11, 0x40 }, /* RF frequency L (placeholder) */
167 { 0x12, 0x0e }, /* RF frequency H (placeholder) */
168 { 0x13, 0x01 } /* start tune */
171 struct mxl301rf_state
*state
;
177 state
= fe
->tuner_priv
;
178 freq
= fe
->dtv_property_cache
.frequency
;
180 /* spur shift function (for analog) */
181 for (i
= 0; i
< ARRAY_SIZE(shf_tab
); i
++) {
182 if (freq
>= (shf_tab
[i
].freq
- shf_tab
[i
].ofst_th
) * 1000 &&
183 freq
<= (shf_tab
[i
].freq
+ shf_tab
[i
].ofst_th
) * 1000) {
184 tune0
[5].val
= shf_tab
[i
].shf_val
;
185 tune0
[6].val
= 0xa0 | shf_tab
[i
].shf_dir
;
189 ret
= raw_write(state
, (u8
*) tune0
, sizeof(tune0
));
192 usleep_range(3000, 4000);
194 /* convert freq to 10.6 fixed point float [MHz] */
196 tmp
= freq
% 1000000;
198 for (i
= 0; i
< 6; i
++) {
208 tune1
[0].val
= f
& 0xff;
209 tune1
[1].val
= f
>> 8;
210 ret
= raw_write(state
, (u8
*) tune1
, sizeof(tune1
));
215 ret
= reg_write(state
, 0x1a, 0x0d);
218 ret
= raw_write(state
, (u8
*) set_idac
, sizeof(set_idac
));
224 dev_warn(&state
->i2c
->dev
, "(%s) failed. [adap%d-fe%d]\n",
225 __func__
, fe
->dvb
->num
, fe
->id
);
229 static const struct reg_val standby_data
[] = {
234 static int mxl301rf_sleep(struct dvb_frontend
*fe
)
236 struct mxl301rf_state
*state
;
239 state
= fe
->tuner_priv
;
240 ret
= raw_write(state
, (u8
*)standby_data
, sizeof(standby_data
));
242 dev_warn(&state
->i2c
->dev
, "(%s) failed. [adap%d-fe%d]\n",
243 __func__
, fe
->dvb
->num
, fe
->id
);
248 /* init sequence is not public.
249 * the parent must have init'ed the device.
252 static int mxl301rf_init(struct dvb_frontend
*fe
)
254 struct mxl301rf_state
*state
;
257 state
= fe
->tuner_priv
;
259 ret
= reg_write(state
, 0x01, 0x01);
261 dev_warn(&state
->i2c
->dev
, "(%s) failed. [adap%d-fe%d]\n",
262 __func__
, fe
->dvb
->num
, fe
->id
);
268 /* I2C driver functions */
270 static const struct dvb_tuner_ops mxl301rf_ops
= {
272 .name
= "MaxLinear MxL301RF",
274 .frequency_min_hz
= 93 * MHz
,
275 .frequency_max_hz
= 803 * MHz
+ 142857,
278 .init
= mxl301rf_init
,
279 .sleep
= mxl301rf_sleep
,
281 .set_params
= mxl301rf_set_params
,
282 .get_rf_strength
= mxl301rf_get_rf_strength
,
286 static int mxl301rf_probe(struct i2c_client
*client
,
287 const struct i2c_device_id
*id
)
289 struct mxl301rf_state
*state
;
290 struct mxl301rf_config
*cfg
;
291 struct dvb_frontend
*fe
;
293 state
= kzalloc(sizeof(*state
), GFP_KERNEL
);
298 cfg
= client
->dev
.platform_data
;
300 memcpy(&state
->cfg
, cfg
, sizeof(state
->cfg
));
302 fe
->tuner_priv
= state
;
303 memcpy(&fe
->ops
.tuner_ops
, &mxl301rf_ops
, sizeof(mxl301rf_ops
));
305 i2c_set_clientdata(client
, &state
->cfg
);
306 dev_info(&client
->dev
, "MaxLinear MxL301RF attached.\n");
310 static int mxl301rf_remove(struct i2c_client
*client
)
312 struct mxl301rf_state
*state
;
314 state
= cfg_to_state(i2c_get_clientdata(client
));
315 state
->cfg
.fe
->tuner_priv
= NULL
;
321 static const struct i2c_device_id mxl301rf_id
[] = {
325 MODULE_DEVICE_TABLE(i2c
, mxl301rf_id
);
327 static struct i2c_driver mxl301rf_driver
= {
331 .probe
= mxl301rf_probe
,
332 .remove
= mxl301rf_remove
,
333 .id_table
= mxl301rf_id
,
336 module_i2c_driver(mxl301rf_driver
);
338 MODULE_DESCRIPTION("MaxLinear MXL301RF tuner");
339 MODULE_AUTHOR("Akihiro TSUKADA");
340 MODULE_LICENSE("GPL");