2 * Maxim Integrated MAX2175 RF to Bits tuner driver
4 * This driver & most of the hard coded values are based on the reference
5 * application delivered by Maxim for this device.
7 * Copyright (C) 2016 Maxim Integrated Products
8 * Copyright (C) 2017 Renesas Electronics Corporation
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 #include <linux/clk.h>
21 #include <linux/delay.h>
22 #include <linux/errno.h>
23 #include <linux/i2c.h>
24 #include <linux/kernel.h>
25 #include <linux/math64.h>
26 #include <linux/max2175.h>
27 #include <linux/module.h>
29 #include <linux/regmap.h>
30 #include <linux/slab.h>
31 #include <media/v4l2-ctrls.h>
32 #include <media/v4l2-device.h>
36 #define DRIVER_NAME "max2175"
38 #define mxm_dbg(ctx, fmt, arg...) dev_dbg(&ctx->client->dev, fmt, ## arg)
39 #define mxm_err(ctx, fmt, arg...) dev_err(&ctx->client->dev, fmt, ## arg)
42 struct max2175_rxmode
{
43 enum max2175_band band
; /* Associated band */
44 u32 freq
; /* Default freq in Hz */
45 u8 i2s_word_size
; /* Bit value */
48 /* Register map to define preset values */
49 struct max2175_reg_map
{
50 u8 idx
; /* Register index */
51 u8 val
; /* Register value */
54 static const struct max2175_rxmode eu_rx_modes
[] = {
56 [MAX2175_EU_FM_1_2
] = { MAX2175_BAND_FM
, 98256000, 1 },
57 [MAX2175_DAB_1_2
] = { MAX2175_BAND_VHF
, 182640000, 0 },
60 static const struct max2175_rxmode na_rx_modes
[] = {
62 [MAX2175_NA_FM_1_0
] = { MAX2175_BAND_FM
, 98255520, 1 },
63 [MAX2175_NA_FM_2_0
] = { MAX2175_BAND_FM
, 98255520, 6 },
68 * Based on Maxim MAX2175 Register Table revision: 130p10
70 static const u8 full_fm_eu_1p0
[] = {
71 0x15, 0x04, 0xb8, 0xe3, 0x35, 0x18, 0x7c, 0x00,
72 0x00, 0x7d, 0x40, 0x08, 0x70, 0x7a, 0x88, 0x91,
73 0x61, 0x61, 0x61, 0x61, 0x5a, 0x0f, 0x34, 0x1c,
74 0x14, 0x88, 0x33, 0x02, 0x00, 0x09, 0x00, 0x65,
75 0x9f, 0x2b, 0x80, 0x00, 0x95, 0x05, 0x2c, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
77 0x4a, 0x08, 0xa8, 0x0e, 0x0e, 0x2f, 0x7e, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x5e, 0xa9,
80 0xae, 0xbb, 0x57, 0x18, 0x3b, 0x03, 0x3b, 0x64,
81 0x40, 0x60, 0x00, 0x2a, 0xbf, 0x3f, 0xff, 0x9f,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
83 0xff, 0xfc, 0xef, 0x1c, 0x40, 0x00, 0x00, 0x02,
84 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x40, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
87 0x00, 0x47, 0x00, 0x00, 0x11, 0x3f, 0x22, 0x00,
88 0xf1, 0x00, 0x41, 0x03, 0xb0, 0x00, 0x00, 0x00,
92 static const u8 full_fm_na_1p0
[] = {
93 0x13, 0x08, 0x8d, 0xc0, 0x35, 0x18, 0x7d, 0x3f,
94 0x7d, 0x75, 0x40, 0x08, 0x70, 0x7a, 0x88, 0x91,
95 0x61, 0x61, 0x61, 0x61, 0x5c, 0x0f, 0x34, 0x1c,
96 0x14, 0x88, 0x33, 0x02, 0x00, 0x01, 0x00, 0x65,
97 0x9f, 0x2b, 0x80, 0x00, 0x95, 0x05, 0x2c, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
99 0x4a, 0x08, 0xa8, 0x0e, 0x0e, 0xaf, 0x7e, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x5e, 0xa9,
102 0xae, 0xbb, 0x57, 0x18, 0x3b, 0x03, 0x3b, 0x64,
103 0x40, 0x60, 0x00, 0x2a, 0xbf, 0x3f, 0xff, 0x9f,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
105 0xff, 0xfc, 0xef, 0x1c, 0x40, 0x00, 0x00, 0x02,
106 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x40, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
109 0x00, 0x35, 0x00, 0x00, 0x11, 0x3f, 0x22, 0x00,
110 0xf1, 0x00, 0x41, 0x03, 0xb0, 0x00, 0x00, 0x00,
114 /* DAB1.2 settings */
115 static const struct max2175_reg_map dab12_map
[] = {
116 { 0x01, 0x13 }, { 0x02, 0x0d }, { 0x03, 0x15 }, { 0x04, 0x55 },
117 { 0x05, 0x0a }, { 0x06, 0xa0 }, { 0x07, 0x40 }, { 0x08, 0x00 },
118 { 0x09, 0x00 }, { 0x0a, 0x7d }, { 0x0b, 0x4a }, { 0x0c, 0x28 },
119 { 0x0e, 0x43 }, { 0x0f, 0xb5 }, { 0x10, 0x31 }, { 0x11, 0x9e },
120 { 0x12, 0x68 }, { 0x13, 0x9e }, { 0x14, 0x68 }, { 0x15, 0x58 },
121 { 0x16, 0x2f }, { 0x17, 0x3f }, { 0x18, 0x40 }, { 0x1a, 0x88 },
122 { 0x1b, 0xaa }, { 0x1c, 0x9a }, { 0x1d, 0x00 }, { 0x1e, 0x00 },
123 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x00 }, { 0x26, 0x00 },
124 { 0x27, 0x00 }, { 0x32, 0x08 }, { 0x33, 0xf8 }, { 0x36, 0x2d },
125 { 0x37, 0x7e }, { 0x55, 0xaf }, { 0x56, 0x3f }, { 0x57, 0xf8 },
126 { 0x58, 0x99 }, { 0x76, 0x00 }, { 0x77, 0x00 }, { 0x78, 0x02 },
127 { 0x79, 0x40 }, { 0x82, 0x00 }, { 0x83, 0x00 }, { 0x85, 0x00 },
131 /* EU FM 1.2 settings */
132 static const struct max2175_reg_map fmeu1p2_map
[] = {
133 { 0x01, 0x15 }, { 0x02, 0x04 }, { 0x03, 0xb8 }, { 0x04, 0xe3 },
134 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7c }, { 0x08, 0x00 },
135 { 0x09, 0x00 }, { 0x0a, 0x73 }, { 0x0b, 0x40 }, { 0x0c, 0x08 },
136 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
137 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5a },
138 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
139 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
140 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
141 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0x2f },
142 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
143 { 0x58, 0x9f }, { 0x76, 0xac }, { 0x77, 0x40 }, { 0x78, 0x00 },
144 { 0x79, 0x00 }, { 0x82, 0x47 }, { 0x83, 0x00 }, { 0x85, 0x11 },
148 /* FM NA 1.0 settings */
149 static const struct max2175_reg_map fmna1p0_map
[] = {
150 { 0x01, 0x13 }, { 0x02, 0x08 }, { 0x03, 0x8d }, { 0x04, 0xc0 },
151 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7d }, { 0x08, 0x3f },
152 { 0x09, 0x7d }, { 0x0a, 0x75 }, { 0x0b, 0x40 }, { 0x0c, 0x08 },
153 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
154 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5c },
155 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
156 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
157 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
158 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0xaf },
159 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
160 { 0x58, 0x9f }, { 0x76, 0xa6 }, { 0x77, 0x40 }, { 0x78, 0x00 },
161 { 0x79, 0x00 }, { 0x82, 0x35 }, { 0x83, 0x00 }, { 0x85, 0x11 },
165 /* FM NA 2.0 settings */
166 static const struct max2175_reg_map fmna2p0_map
[] = {
167 { 0x01, 0x13 }, { 0x02, 0x08 }, { 0x03, 0x8d }, { 0x04, 0xc0 },
168 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7c }, { 0x08, 0x54 },
169 { 0x09, 0xa7 }, { 0x0a, 0x55 }, { 0x0b, 0x42 }, { 0x0c, 0x48 },
170 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
171 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5c },
172 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
173 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
174 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
175 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0xaf },
176 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
177 { 0x58, 0x9f }, { 0x76, 0xac }, { 0x77, 0xc0 }, { 0x78, 0x00 },
178 { 0x79, 0x00 }, { 0x82, 0x6b }, { 0x83, 0x00 }, { 0x85, 0x11 },
182 static const u16 ch_coeff_dab1
[] = {
183 0x001c, 0x0007, 0xffcd, 0x0056, 0xffa4, 0x0033, 0x0027, 0xff61,
184 0x010e, 0xfec0, 0x0106, 0xffb8, 0xff1c, 0x023c, 0xfcb2, 0x039b,
185 0xfd4e, 0x0055, 0x036a, 0xf7de, 0x0d21, 0xee72, 0x1499, 0x6a51,
188 static const u16 ch_coeff_fmeu
[] = {
189 0x0000, 0xffff, 0x0001, 0x0002, 0xfffa, 0xffff, 0x0015, 0xffec,
190 0xffde, 0x0054, 0xfff9, 0xff52, 0x00b8, 0x00a2, 0xfe0a, 0x00af,
191 0x02e3, 0xfc14, 0xfe89, 0x089d, 0xfa2e, 0xf30f, 0x25be, 0x4eb6,
194 static const u16 eq_coeff_fmeu1_ra02_m6db
[] = {
195 0x0040, 0xffc6, 0xfffa, 0x002c, 0x000d, 0xff90, 0x0037, 0x006e,
196 0xffc0, 0xff5b, 0x006a, 0x00f0, 0xff57, 0xfe94, 0x0112, 0x0252,
197 0xfe0c, 0xfc6a, 0x0385, 0x0553, 0xfa49, 0xf789, 0x0b91, 0x1a10,
200 static const u16 ch_coeff_fmna
[] = {
201 0x0001, 0x0003, 0xfffe, 0xfff4, 0x0000, 0x001f, 0x000c, 0xffbc,
202 0xffd3, 0x007d, 0x0075, 0xff33, 0xff01, 0x0131, 0x01ef, 0xfe60,
203 0xfc7a, 0x020e, 0x0656, 0xfd94, 0xf395, 0x02ab, 0x2857, 0x3d3f,
206 static const u16 eq_coeff_fmna1_ra02_m6db
[] = {
207 0xfff1, 0xffe1, 0xffef, 0x000e, 0x0030, 0x002f, 0xfff6, 0xffa7,
208 0xff9d, 0x000a, 0x00a2, 0x00b5, 0xffea, 0xfed9, 0xfec5, 0x003d,
209 0x0217, 0x021b, 0xff5a, 0xfc2b, 0xfcbd, 0x02c4, 0x0ac3, 0x0e85,
212 static const u8 adc_presets
[2][23] = {
214 0x83, 0x00, 0xcf, 0xb4, 0x0f, 0x2c, 0x0c, 0x49,
215 0x00, 0x00, 0x00, 0x8c, 0x02, 0x02, 0x00, 0x04,
216 0xec, 0x82, 0x4b, 0xcc, 0x01, 0x88, 0x0c,
219 0x83, 0x00, 0xcf, 0xb4, 0x0f, 0x2c, 0x0c, 0x49,
220 0x00, 0x00, 0x00, 0x8c, 0x02, 0x20, 0x33, 0x8c,
221 0x57, 0xd7, 0x59, 0xb7, 0x65, 0x0e, 0x0c,
226 static const struct v4l2_frequency_band eu_bands_rf
= {
228 .type
= V4L2_TUNER_RF
,
230 .capability
= V4L2_TUNER_CAP_1HZ
| V4L2_TUNER_CAP_FREQ_BANDS
,
231 .rangelow
= 65000000,
232 .rangehigh
= 240000000,
235 static const struct v4l2_frequency_band na_bands_rf
= {
237 .type
= V4L2_TUNER_RF
,
239 .capability
= V4L2_TUNER_CAP_1HZ
| V4L2_TUNER_CAP_FREQ_BANDS
,
240 .rangelow
= 65000000,
241 .rangehigh
= 108000000,
244 /* Regmap settings */
245 static const struct regmap_range max2175_regmap_volatile_range
[] = {
246 regmap_reg_range(0x30, 0x35),
247 regmap_reg_range(0x3a, 0x45),
248 regmap_reg_range(0x59, 0x5e),
249 regmap_reg_range(0x73, 0x75),
252 static const struct regmap_access_table max2175_volatile_regs
= {
253 .yes_ranges
= max2175_regmap_volatile_range
,
254 .n_yes_ranges
= ARRAY_SIZE(max2175_regmap_volatile_range
),
257 static const struct reg_default max2175_reg_defaults
[] = {
261 static const struct regmap_config max2175_regmap_config
= {
264 .max_register
= 0xff,
265 .reg_defaults
= max2175_reg_defaults
,
266 .num_reg_defaults
= ARRAY_SIZE(max2175_reg_defaults
),
267 .volatile_table
= &max2175_volatile_regs
,
268 .cache_type
= REGCACHE_FLAT
,
272 struct v4l2_subdev sd
; /* Sub-device */
273 struct i2c_client
*client
; /* I2C client */
276 struct v4l2_ctrl_handler ctrl_hdl
;
277 struct v4l2_ctrl
*lna_gain
; /* LNA gain value */
278 struct v4l2_ctrl
*if_gain
; /* I/F gain value */
279 struct v4l2_ctrl
*pll_lock
; /* PLL lock */
280 struct v4l2_ctrl
*i2s_en
; /* I2S output enable */
281 struct v4l2_ctrl
*hsls
; /* High-side/Low-side polarity */
282 struct v4l2_ctrl
*rx_mode
; /* Receive mode */
285 struct regmap
*regmap
;
287 /* Cached configuration */
288 u32 freq
; /* Tuned freq In Hz */
289 const struct max2175_rxmode
*rx_modes
; /* EU or NA modes */
290 const struct v4l2_frequency_band
*bands_rf
; /* EU or NA bands */
292 /* Device settings */
293 unsigned long xtal_freq
; /* Ref Oscillator freq in Hz */
295 bool master
; /* Master/Slave */
296 bool am_hiz
; /* AM Hi-Z filter */
303 /* Driver private variables */
304 bool mode_resolved
; /* Flag to sanity check settings */
307 static inline struct max2175
*max2175_from_sd(struct v4l2_subdev
*sd
)
309 return container_of(sd
, struct max2175
, sd
);
312 static inline struct max2175
*max2175_from_ctrl_hdl(struct v4l2_ctrl_handler
*h
)
314 return container_of(h
, struct max2175
, ctrl_hdl
);
317 /* Get bitval of a given val */
318 static inline u8
max2175_get_bitval(u8 val
, u8 msb
, u8 lsb
)
320 return (val
& GENMASK(msb
, lsb
)) >> lsb
;
323 /* Read/Write bit(s) on top of regmap */
324 static int max2175_read(struct max2175
*ctx
, u8 idx
, u8
*val
)
329 ret
= regmap_read(ctx
->regmap
, idx
, ®val
);
331 mxm_err(ctx
, "read ret(%d): idx 0x%02x\n", ret
, idx
);
338 static int max2175_write(struct max2175
*ctx
, u8 idx
, u8 val
)
342 ret
= regmap_write(ctx
->regmap
, idx
, val
);
344 mxm_err(ctx
, "write ret(%d): idx 0x%02x val 0x%02x\n",
350 static u8
max2175_read_bits(struct max2175
*ctx
, u8 idx
, u8 msb
, u8 lsb
)
354 if (max2175_read(ctx
, idx
, &val
))
357 return max2175_get_bitval(val
, msb
, lsb
);
360 static int max2175_write_bits(struct max2175
*ctx
, u8 idx
,
361 u8 msb
, u8 lsb
, u8 newval
)
363 int ret
= regmap_update_bits(ctx
->regmap
, idx
, GENMASK(msb
, lsb
),
367 mxm_err(ctx
, "wbits ret(%d): idx 0x%02x\n", ret
, idx
);
372 static int max2175_write_bit(struct max2175
*ctx
, u8 idx
, u8 bit
, u8 newval
)
374 return max2175_write_bits(ctx
, idx
, bit
, bit
, newval
);
377 /* Checks expected pattern every msec until timeout */
378 static int max2175_poll_timeout(struct max2175
*ctx
, u8 idx
, u8 msb
, u8 lsb
,
379 u8 exp_bitval
, u32 timeout_us
)
383 return regmap_read_poll_timeout(ctx
->regmap
, idx
, val
,
384 (max2175_get_bitval(val
, msb
, lsb
) == exp_bitval
),
388 static int max2175_poll_csm_ready(struct max2175
*ctx
)
392 ret
= max2175_poll_timeout(ctx
, 69, 1, 1, 0, 50000);
394 mxm_err(ctx
, "csm not ready\n");
399 #define MAX2175_IS_BAND_AM(ctx) \
400 (max2175_read_bits(ctx, 5, 1, 0) == MAX2175_BAND_AM)
402 #define MAX2175_IS_BAND_VHF(ctx) \
403 (max2175_read_bits(ctx, 5, 1, 0) == MAX2175_BAND_VHF)
405 #define MAX2175_IS_FM_MODE(ctx) \
406 (max2175_read_bits(ctx, 12, 5, 4) == 0)
408 #define MAX2175_IS_FMHD_MODE(ctx) \
409 (max2175_read_bits(ctx, 12, 5, 4) == 1)
411 #define MAX2175_IS_DAB_MODE(ctx) \
412 (max2175_read_bits(ctx, 12, 5, 4) == 2)
414 static int max2175_band_from_freq(u32 freq
)
416 if (freq
>= 144000 && freq
<= 26100000)
417 return MAX2175_BAND_AM
;
418 else if (freq
>= 65000000 && freq
<= 108000000)
419 return MAX2175_BAND_FM
;
421 return MAX2175_BAND_VHF
;
424 static void max2175_i2s_enable(struct max2175
*ctx
, bool enable
)
427 /* Stuff bits are zeroed */
428 max2175_write_bits(ctx
, 104, 3, 0, 2);
431 max2175_write_bits(ctx
, 104, 3, 0, 9);
432 mxm_dbg(ctx
, "i2s %sabled\n", enable
? "en" : "dis");
435 static void max2175_set_filter_coeffs(struct max2175
*ctx
, u8 m_sel
,
436 u8 bank
, const u16
*coeffs
)
439 u8 coeff_addr
, upper_address
= 24;
441 mxm_dbg(ctx
, "set_filter_coeffs: m_sel %d bank %d\n", m_sel
, bank
);
442 max2175_write_bits(ctx
, 114, 5, 4, m_sel
);
447 for (i
= 0; i
< upper_address
; i
++) {
448 coeff_addr
= i
+ bank
* 24;
449 max2175_write(ctx
, 115, coeffs
[i
] >> 8);
450 max2175_write(ctx
, 116, coeffs
[i
]);
451 max2175_write(ctx
, 117, coeff_addr
| 1 << 7);
453 max2175_write_bit(ctx
, 117, 7, 0);
456 static void max2175_load_fmeu_1p2(struct max2175
*ctx
)
460 for (i
= 0; i
< ARRAY_SIZE(fmeu1p2_map
); i
++)
461 max2175_write(ctx
, fmeu1p2_map
[i
].idx
, fmeu1p2_map
[i
].val
);
463 ctx
->decim_ratio
= 36;
465 /* Load the Channel Filter Coefficients into channel filter bank #2 */
466 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0, ch_coeff_fmeu
);
467 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
468 eq_coeff_fmeu1_ra02_m6db
);
471 static void max2175_load_dab_1p2(struct max2175
*ctx
)
475 for (i
= 0; i
< ARRAY_SIZE(dab12_map
); i
++)
476 max2175_write(ctx
, dab12_map
[i
].idx
, dab12_map
[i
].val
);
478 ctx
->decim_ratio
= 1;
480 /* Load the Channel Filter Coefficients into channel filter bank #2 */
481 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 2, ch_coeff_dab1
);
484 static void max2175_load_fmna_1p0(struct max2175
*ctx
)
488 for (i
= 0; i
< ARRAY_SIZE(fmna1p0_map
); i
++)
489 max2175_write(ctx
, fmna1p0_map
[i
].idx
, fmna1p0_map
[i
].val
);
492 static void max2175_load_fmna_2p0(struct max2175
*ctx
)
496 for (i
= 0; i
< ARRAY_SIZE(fmna2p0_map
); i
++)
497 max2175_write(ctx
, fmna2p0_map
[i
].idx
, fmna2p0_map
[i
].val
);
500 static void max2175_set_bbfilter(struct max2175
*ctx
)
502 if (MAX2175_IS_BAND_AM(ctx
)) {
503 max2175_write_bits(ctx
, 12, 3, 0, ctx
->rom_bbf_bw_am
);
504 mxm_dbg(ctx
, "set_bbfilter AM: rom %d\n", ctx
->rom_bbf_bw_am
);
505 } else if (MAX2175_IS_DAB_MODE(ctx
)) {
506 max2175_write_bits(ctx
, 12, 3, 0, ctx
->rom_bbf_bw_dab
);
507 mxm_dbg(ctx
, "set_bbfilter DAB: rom %d\n", ctx
->rom_bbf_bw_dab
);
509 max2175_write_bits(ctx
, 12, 3, 0, ctx
->rom_bbf_bw_fm
);
510 mxm_dbg(ctx
, "set_bbfilter FM: rom %d\n", ctx
->rom_bbf_bw_fm
);
514 static bool max2175_set_csm_mode(struct max2175
*ctx
,
515 enum max2175_csm_mode new_mode
)
517 int ret
= max2175_poll_csm_ready(ctx
);
522 max2175_write_bits(ctx
, 0, 2, 0, new_mode
);
523 mxm_dbg(ctx
, "set csm new mode %d\n", new_mode
);
525 /* Wait for a fixed settle down time depending on new mode */
527 case MAX2175_PRESET_TUNE
:
528 usleep_range(51100, 51500); /* 51.1ms */
531 * Other mode switches need different sleep values depending on band &
538 return max2175_poll_csm_ready(ctx
);
541 static int max2175_csm_action(struct max2175
*ctx
,
542 enum max2175_csm_mode action
)
546 mxm_dbg(ctx
, "csm_action: %d\n", action
);
548 /* Other actions can be added in future when needed */
549 ret
= max2175_set_csm_mode(ctx
, MAX2175_LOAD_TO_BUFFER
);
553 return max2175_set_csm_mode(ctx
, MAX2175_PRESET_TUNE
);
556 static int max2175_set_lo_freq(struct max2175
*ctx
, u32 lo_freq
)
558 u8 lo_mult
, loband_bits
= 0, vcodiv_bits
= 0;
559 u32 int_desired
, frac_desired
;
560 enum max2175_band band
;
563 band
= max2175_read_bits(ctx
, 5, 1, 0);
565 case MAX2175_BAND_AM
:
568 case MAX2175_BAND_FM
:
569 if (lo_freq
<= 74700000) {
571 } else if (lo_freq
> 74700000 && lo_freq
<= 110000000) {
580 case MAX2175_BAND_VHF
:
581 if (lo_freq
<= 210000000)
596 if (band
== MAX2175_BAND_L
)
601 int_desired
= lo_freq
/ ctx
->xtal_freq
;
602 frac_desired
= div_u64((u64
)(lo_freq
% ctx
->xtal_freq
) << 20,
605 /* Check CSM is not busy */
606 ret
= max2175_poll_csm_ready(ctx
);
610 mxm_dbg(ctx
, "lo_mult %u int %u frac %u\n",
611 lo_mult
, int_desired
, frac_desired
);
613 /* Write the calculated values to the appropriate registers */
614 max2175_write(ctx
, 1, int_desired
);
615 max2175_write_bits(ctx
, 2, 3, 0, (frac_desired
>> 16) & 0xf);
616 max2175_write(ctx
, 3, frac_desired
>> 8);
617 max2175_write(ctx
, 4, frac_desired
);
618 max2175_write_bits(ctx
, 5, 3, 2, loband_bits
);
619 max2175_write_bits(ctx
, 6, 7, 6, vcodiv_bits
);
625 * Helper similar to DIV_ROUND_CLOSEST but an inline function that accepts s64
626 * dividend and s32 divisor
628 static inline s64
max2175_round_closest(s64 dividend
, s32 divisor
)
630 if ((dividend
> 0 && divisor
> 0) || (dividend
< 0 && divisor
< 0))
631 return div_s64(dividend
+ divisor
/ 2, divisor
);
633 return div_s64(dividend
- divisor
/ 2, divisor
);
636 static int max2175_set_nco_freq(struct max2175
*ctx
, s32 nco_freq
)
638 s32 clock_rate
= ctx
->xtal_freq
/ ctx
->decim_ratio
;
639 u32 nco_reg
, abs_nco_freq
= abs(nco_freq
);
643 if (abs_nco_freq
< clock_rate
/ 2) {
644 nco_val_desired
= 2 * nco_freq
;
646 nco_val_desired
= 2LL * (clock_rate
- abs_nco_freq
);
648 nco_val_desired
= -nco_val_desired
;
651 nco_reg
= max2175_round_closest(nco_val_desired
<< 20, clock_rate
);
656 /* Check CSM is not busy */
657 ret
= max2175_poll_csm_ready(ctx
);
661 mxm_dbg(ctx
, "freq %d desired %lld reg %u\n",
662 nco_freq
, nco_val_desired
, nco_reg
);
664 /* Write the calculated values to the appropriate registers */
665 max2175_write_bits(ctx
, 7, 4, 0, (nco_reg
>> 16) & 0x1f);
666 max2175_write(ctx
, 8, nco_reg
>> 8);
667 max2175_write(ctx
, 9, nco_reg
);
672 static int max2175_set_rf_freq_non_am_bands(struct max2175
*ctx
, u64 freq
,
675 s64 adj_freq
, low_if_freq
;
678 mxm_dbg(ctx
, "rf_freq: non AM bands\n");
680 if (MAX2175_IS_FM_MODE(ctx
))
681 low_if_freq
= 128000;
682 else if (MAX2175_IS_FMHD_MODE(ctx
))
683 low_if_freq
= 228000;
685 return max2175_set_lo_freq(ctx
, freq
);
687 if (MAX2175_IS_BAND_VHF(ctx
) == (lo_pos
== MAX2175_LO_ABOVE_DESIRED
))
688 adj_freq
= freq
+ low_if_freq
;
690 adj_freq
= freq
- low_if_freq
;
692 ret
= max2175_set_lo_freq(ctx
, adj_freq
);
696 return max2175_set_nco_freq(ctx
, -low_if_freq
);
699 static int max2175_set_rf_freq(struct max2175
*ctx
, u64 freq
, u32 lo_pos
)
703 if (MAX2175_IS_BAND_AM(ctx
))
704 ret
= max2175_set_nco_freq(ctx
, freq
);
706 ret
= max2175_set_rf_freq_non_am_bands(ctx
, freq
, lo_pos
);
708 mxm_dbg(ctx
, "set_rf_freq: ret %d freq %llu\n", ret
, freq
);
713 static int max2175_tune_rf_freq(struct max2175
*ctx
, u64 freq
, u32 hsls
)
717 ret
= max2175_set_rf_freq(ctx
, freq
, hsls
);
721 ret
= max2175_csm_action(ctx
, MAX2175_BUFFER_PLUS_PRESET_TUNE
);
725 mxm_dbg(ctx
, "tune_rf_freq: old %u new %llu\n", ctx
->freq
, freq
);
731 static void max2175_set_hsls(struct max2175
*ctx
, u32 lo_pos
)
733 mxm_dbg(ctx
, "set_hsls: lo_pos %u\n", lo_pos
);
735 if ((lo_pos
== MAX2175_LO_BELOW_DESIRED
) == MAX2175_IS_BAND_VHF(ctx
))
736 max2175_write_bit(ctx
, 5, 4, 1);
738 max2175_write_bit(ctx
, 5, 4, 0);
741 static void max2175_set_eu_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
744 case MAX2175_EU_FM_1_2
:
745 max2175_load_fmeu_1p2(ctx
);
748 case MAX2175_DAB_1_2
:
749 max2175_load_dab_1p2(ctx
);
752 /* Master is the default setting */
754 max2175_write_bit(ctx
, 30, 7, 1);
757 static void max2175_set_na_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
760 case MAX2175_NA_FM_1_0
:
761 max2175_load_fmna_1p0(ctx
);
763 case MAX2175_NA_FM_2_0
:
764 max2175_load_fmna_2p0(ctx
);
767 /* Master is the default setting */
769 max2175_write_bit(ctx
, 30, 7, 1);
771 ctx
->decim_ratio
= 27;
773 /* Load the Channel Filter Coefficients into channel filter bank #2 */
774 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0, ch_coeff_fmna
);
775 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
776 eq_coeff_fmna1_ra02_m6db
);
779 static int max2175_set_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
781 mxm_dbg(ctx
, "set_rx_mode: %u am_hiz %u\n", rx_mode
, ctx
->am_hiz
);
782 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
)
783 max2175_set_eu_rx_mode(ctx
, rx_mode
);
785 max2175_set_na_rx_mode(ctx
, rx_mode
);
788 mxm_dbg(ctx
, "setting AM HiZ related config\n");
789 max2175_write_bit(ctx
, 50, 5, 1);
790 max2175_write_bit(ctx
, 90, 7, 1);
791 max2175_write_bits(ctx
, 73, 1, 0, 2);
792 max2175_write_bits(ctx
, 80, 5, 0, 33);
795 /* Load BB filter trim values saved in ROM */
796 max2175_set_bbfilter(ctx
);
799 max2175_set_hsls(ctx
, ctx
->hsls
->cur
.val
);
801 /* Use i2s enable settings */
802 max2175_i2s_enable(ctx
, ctx
->i2s_en
->cur
.val
);
804 ctx
->mode_resolved
= true;
809 static int max2175_rx_mode_from_freq(struct max2175
*ctx
, u32 freq
, u32
*mode
)
812 int band
= max2175_band_from_freq(freq
);
814 /* Pick the first match always */
815 for (i
= 0; i
<= ctx
->rx_mode
->maximum
; i
++) {
816 if (ctx
->rx_modes
[i
].band
== band
) {
818 mxm_dbg(ctx
, "rx_mode_from_freq: freq %u mode %d\n",
827 static bool max2175_freq_rx_mode_valid(struct max2175
*ctx
,
830 int band
= max2175_band_from_freq(freq
);
832 return (ctx
->rx_modes
[mode
].band
== band
);
835 static void max2175_load_adc_presets(struct max2175
*ctx
)
839 for (i
= 0; i
< ARRAY_SIZE(adc_presets
); i
++)
840 for (j
= 0; j
< ARRAY_SIZE(adc_presets
[0]); j
++)
841 max2175_write(ctx
, 146 + j
+ i
* 55, adc_presets
[i
][j
]);
844 static int max2175_init_power_manager(struct max2175
*ctx
)
848 /* Execute on-chip power-up/calibration */
849 max2175_write_bit(ctx
, 99, 2, 0);
850 usleep_range(1000, 1500);
851 max2175_write_bit(ctx
, 99, 2, 1);
853 /* Wait for the power manager to finish. */
854 ret
= max2175_poll_timeout(ctx
, 69, 7, 7, 1, 50000);
856 mxm_err(ctx
, "init pm failed\n");
861 static int max2175_recalibrate_adc(struct max2175
*ctx
)
865 /* ADC Re-calibration */
866 max2175_write(ctx
, 150, 0xff);
867 max2175_write(ctx
, 205, 0xff);
868 max2175_write(ctx
, 147, 0x20);
869 max2175_write(ctx
, 147, 0x00);
870 max2175_write(ctx
, 202, 0x20);
871 max2175_write(ctx
, 202, 0x00);
873 ret
= max2175_poll_timeout(ctx
, 69, 4, 3, 3, 50000);
875 mxm_err(ctx
, "adc recalibration failed\n");
880 static u8
max2175_read_rom(struct max2175
*ctx
, u8 row
)
884 max2175_write_bit(ctx
, 56, 4, 0);
885 max2175_write_bits(ctx
, 56, 3, 0, row
);
887 usleep_range(2000, 2500);
888 max2175_read(ctx
, 58, &data
);
890 max2175_write_bits(ctx
, 56, 3, 0, 0);
892 mxm_dbg(ctx
, "read_rom: row %d data 0x%02x\n", row
, data
);
897 static void max2175_load_from_rom(struct max2175
*ctx
)
901 data
= max2175_read_rom(ctx
, 0);
902 ctx
->rom_bbf_bw_am
= data
& 0x0f;
903 max2175_write_bits(ctx
, 81, 3, 0, data
>> 4);
905 data
= max2175_read_rom(ctx
, 1);
906 ctx
->rom_bbf_bw_fm
= data
& 0x0f;
907 ctx
->rom_bbf_bw_dab
= data
>> 4;
909 data
= max2175_read_rom(ctx
, 2);
910 max2175_write_bits(ctx
, 82, 4, 0, data
& 0x1f);
911 max2175_write_bits(ctx
, 82, 7, 5, data
>> 5);
913 data
= max2175_read_rom(ctx
, 3);
916 data
|= (max2175_read_rom(ctx
, 7) & 0x40) >> 2;
920 data
= (data
& 0xf0) >> 4;
921 data
|= (max2175_read_rom(ctx
, 7) & 0x80) >> 3;
925 max2175_write_bits(ctx
, 80, 5, 0, data
+ 31);
927 data
= max2175_read_rom(ctx
, 6);
928 max2175_write_bits(ctx
, 81, 7, 6, data
>> 6);
931 static void max2175_load_full_fm_eu_1p0(struct max2175
*ctx
)
935 for (i
= 0; i
< ARRAY_SIZE(full_fm_eu_1p0
); i
++)
936 max2175_write(ctx
, i
+ 1, full_fm_eu_1p0
[i
]);
938 usleep_range(5000, 5500);
939 ctx
->decim_ratio
= 36;
942 static void max2175_load_full_fm_na_1p0(struct max2175
*ctx
)
946 for (i
= 0; i
< ARRAY_SIZE(full_fm_na_1p0
); i
++)
947 max2175_write(ctx
, i
+ 1, full_fm_na_1p0
[i
]);
949 usleep_range(5000, 5500);
950 ctx
->decim_ratio
= 27;
953 static int max2175_core_init(struct max2175
*ctx
, u32 refout_bits
)
957 /* MAX2175 uses 36.864MHz clock for EU & 40.154MHz for NA region */
958 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
)
959 max2175_load_full_fm_eu_1p0(ctx
);
961 max2175_load_full_fm_na_1p0(ctx
);
963 /* The default settings assume master */
965 max2175_write_bit(ctx
, 30, 7, 1);
967 mxm_dbg(ctx
, "refout_bits %u\n", refout_bits
);
970 max2175_write_bits(ctx
, 56, 7, 5, refout_bits
);
973 max2175_write_bit(ctx
, 99, 1, 0);
974 usleep_range(1000, 1500);
975 max2175_write_bit(ctx
, 99, 1, 1);
977 /* Load ADC preset values */
978 max2175_load_adc_presets(ctx
);
980 /* Initialize the power management state machine */
981 ret
= max2175_init_power_manager(ctx
);
985 /* Recalibrate ADC */
986 ret
= max2175_recalibrate_adc(ctx
);
990 /* Load ROM values to appropriate registers */
991 max2175_load_from_rom(ctx
);
993 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
) {
994 /* Load FIR coefficients into bank 0 */
995 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0,
997 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
998 eq_coeff_fmeu1_ra02_m6db
);
1000 /* Load FIR coefficients into bank 0 */
1001 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0,
1003 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
1004 eq_coeff_fmna1_ra02_m6db
);
1006 mxm_dbg(ctx
, "core initialized\n");
1011 static void max2175_s_ctrl_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
1013 /* Load mode. Range check already done */
1014 max2175_set_rx_mode(ctx
, rx_mode
);
1016 mxm_dbg(ctx
, "s_ctrl_rx_mode: %u curr freq %u\n", rx_mode
, ctx
->freq
);
1018 /* Check if current freq valid for mode & update */
1019 if (max2175_freq_rx_mode_valid(ctx
, rx_mode
, ctx
->freq
))
1020 max2175_tune_rf_freq(ctx
, ctx
->freq
, ctx
->hsls
->cur
.val
);
1022 /* Use default freq of mode if current freq is not valid */
1023 max2175_tune_rf_freq(ctx
, ctx
->rx_modes
[rx_mode
].freq
,
1024 ctx
->hsls
->cur
.val
);
1027 static int max2175_s_ctrl(struct v4l2_ctrl
*ctrl
)
1029 struct max2175
*ctx
= max2175_from_ctrl_hdl(ctrl
->handler
);
1031 mxm_dbg(ctx
, "s_ctrl: id 0x%x, val %u\n", ctrl
->id
, ctrl
->val
);
1033 case V4L2_CID_MAX2175_I2S_ENABLE
:
1034 max2175_i2s_enable(ctx
, ctrl
->val
);
1036 case V4L2_CID_MAX2175_HSLS
:
1037 max2175_set_hsls(ctx
, ctrl
->val
);
1039 case V4L2_CID_MAX2175_RX_MODE
:
1040 max2175_s_ctrl_rx_mode(ctx
, ctrl
->val
);
1047 static u32
max2175_get_lna_gain(struct max2175
*ctx
)
1049 enum max2175_band band
= max2175_read_bits(ctx
, 5, 1, 0);
1052 case MAX2175_BAND_AM
:
1053 return max2175_read_bits(ctx
, 51, 3, 0);
1054 case MAX2175_BAND_FM
:
1055 return max2175_read_bits(ctx
, 50, 3, 0);
1056 case MAX2175_BAND_VHF
:
1057 return max2175_read_bits(ctx
, 52, 5, 0);
1063 static int max2175_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
1065 struct max2175
*ctx
= max2175_from_ctrl_hdl(ctrl
->handler
);
1068 case V4L2_CID_RF_TUNER_LNA_GAIN
:
1069 ctrl
->val
= max2175_get_lna_gain(ctx
);
1071 case V4L2_CID_RF_TUNER_IF_GAIN
:
1072 ctrl
->val
= max2175_read_bits(ctx
, 49, 4, 0);
1074 case V4L2_CID_RF_TUNER_PLL_LOCK
:
1075 ctrl
->val
= (max2175_read_bits(ctx
, 60, 7, 6) == 3);
1082 static int max2175_set_freq_and_mode(struct max2175
*ctx
, u32 freq
)
1087 /* Get band from frequency */
1088 ret
= max2175_rx_mode_from_freq(ctx
, freq
, &rx_mode
);
1092 mxm_dbg(ctx
, "set_freq_and_mode: freq %u rx_mode %d\n", freq
, rx_mode
);
1095 max2175_set_rx_mode(ctx
, rx_mode
);
1096 ctx
->rx_mode
->cur
.val
= rx_mode
;
1098 /* Tune to the new freq given */
1099 return max2175_tune_rf_freq(ctx
, freq
, ctx
->hsls
->cur
.val
);
1102 static int max2175_s_frequency(struct v4l2_subdev
*sd
,
1103 const struct v4l2_frequency
*vf
)
1105 struct max2175
*ctx
= max2175_from_sd(sd
);
1109 mxm_dbg(ctx
, "s_freq: new %u curr %u, mode_resolved %d\n",
1110 vf
->frequency
, ctx
->freq
, ctx
->mode_resolved
);
1115 freq
= clamp(vf
->frequency
, ctx
->bands_rf
->rangelow
,
1116 ctx
->bands_rf
->rangehigh
);
1118 /* Check new freq valid for rx_mode if already resolved */
1119 if (ctx
->mode_resolved
&&
1120 max2175_freq_rx_mode_valid(ctx
, ctx
->rx_mode
->cur
.val
, freq
))
1121 ret
= max2175_tune_rf_freq(ctx
, freq
, ctx
->hsls
->cur
.val
);
1123 /* Find default rx_mode for freq and tune to it */
1124 ret
= max2175_set_freq_and_mode(ctx
, freq
);
1126 mxm_dbg(ctx
, "s_freq: ret %d curr %u mode_resolved %d mode %u\n",
1127 ret
, ctx
->freq
, ctx
->mode_resolved
, ctx
->rx_mode
->cur
.val
);
1132 static int max2175_g_frequency(struct v4l2_subdev
*sd
,
1133 struct v4l2_frequency
*vf
)
1135 struct max2175
*ctx
= max2175_from_sd(sd
);
1142 vf
->type
= V4L2_TUNER_RF
;
1143 vf
->frequency
= ctx
->freq
;
1148 static int max2175_enum_freq_bands(struct v4l2_subdev
*sd
,
1149 struct v4l2_frequency_band
*band
)
1151 struct max2175
*ctx
= max2175_from_sd(sd
);
1153 if (band
->tuner
!= 0 || band
->index
!= 0)
1156 *band
= *ctx
->bands_rf
;
1161 static int max2175_g_tuner(struct v4l2_subdev
*sd
, struct v4l2_tuner
*vt
)
1163 struct max2175
*ctx
= max2175_from_sd(sd
);
1168 strlcpy(vt
->name
, "RF", sizeof(vt
->name
));
1169 vt
->type
= V4L2_TUNER_RF
;
1170 vt
->capability
= V4L2_TUNER_CAP_1HZ
| V4L2_TUNER_CAP_FREQ_BANDS
;
1171 vt
->rangelow
= ctx
->bands_rf
->rangelow
;
1172 vt
->rangehigh
= ctx
->bands_rf
->rangehigh
;
1177 static int max2175_s_tuner(struct v4l2_subdev
*sd
, const struct v4l2_tuner
*vt
)
1179 /* Check tuner index is valid */
1186 static const struct v4l2_subdev_tuner_ops max2175_tuner_ops
= {
1187 .s_frequency
= max2175_s_frequency
,
1188 .g_frequency
= max2175_g_frequency
,
1189 .enum_freq_bands
= max2175_enum_freq_bands
,
1190 .g_tuner
= max2175_g_tuner
,
1191 .s_tuner
= max2175_s_tuner
,
1194 static const struct v4l2_subdev_ops max2175_ops
= {
1195 .tuner
= &max2175_tuner_ops
,
1198 static const struct v4l2_ctrl_ops max2175_ctrl_ops
= {
1199 .s_ctrl
= max2175_s_ctrl
,
1200 .g_volatile_ctrl
= max2175_g_volatile_ctrl
,
1204 * I2S output enable/disable configuration. This is a private control.
1205 * Refer to Documentation/media/v4l-drivers/max2175.rst for more details.
1207 static const struct v4l2_ctrl_config max2175_i2s_en
= {
1208 .ops
= &max2175_ctrl_ops
,
1209 .id
= V4L2_CID_MAX2175_I2S_ENABLE
,
1210 .name
= "I2S Enable",
1211 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1220 * HSLS value control LO freq adjacent location configuration.
1221 * Refer to Documentation/media/v4l-drivers/max2175.rst for more details.
1223 static const struct v4l2_ctrl_config max2175_hsls
= {
1224 .ops
= &max2175_ctrl_ops
,
1225 .id
= V4L2_CID_MAX2175_HSLS
,
1226 .name
= "HSLS Above/Below Desired",
1227 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1235 * Rx modes below are a set of preset configurations that decides the tuner's
1236 * sck and sample rate of transmission. They are separate for EU & NA regions.
1237 * Refer to Documentation/media/v4l-drivers/max2175.rst for more details.
1239 static const char * const max2175_ctrl_eu_rx_modes
[] = {
1240 [MAX2175_EU_FM_1_2
] = "EU FM 1.2",
1241 [MAX2175_DAB_1_2
] = "DAB 1.2",
1244 static const char * const max2175_ctrl_na_rx_modes
[] = {
1245 [MAX2175_NA_FM_1_0
] = "NA FM 1.0",
1246 [MAX2175_NA_FM_2_0
] = "NA FM 2.0",
1249 static const struct v4l2_ctrl_config max2175_eu_rx_mode
= {
1250 .ops
= &max2175_ctrl_ops
,
1251 .id
= V4L2_CID_MAX2175_RX_MODE
,
1253 .type
= V4L2_CTRL_TYPE_MENU
,
1254 .max
= ARRAY_SIZE(max2175_ctrl_eu_rx_modes
) - 1,
1256 .qmenu
= max2175_ctrl_eu_rx_modes
,
1259 static const struct v4l2_ctrl_config max2175_na_rx_mode
= {
1260 .ops
= &max2175_ctrl_ops
,
1261 .id
= V4L2_CID_MAX2175_RX_MODE
,
1263 .type
= V4L2_CTRL_TYPE_MENU
,
1264 .max
= ARRAY_SIZE(max2175_ctrl_na_rx_modes
) - 1,
1266 .qmenu
= max2175_ctrl_na_rx_modes
,
1269 static int max2175_refout_load_to_bits(struct i2c_client
*client
, u32 load
,
1274 else if (load
>= 60 && load
<= 70)
1275 *bits
= load
/ 10 - 1;
1282 static int max2175_probe(struct i2c_client
*client
,
1283 const struct i2c_device_id
*id
)
1285 bool master
= true, am_hiz
= false;
1286 u32 refout_load
, refout_bits
= 0; /* REFOUT disabled */
1287 struct v4l2_ctrl_handler
*hdl
;
1288 struct fwnode_handle
*fwnode
;
1289 struct device_node
*np
;
1290 struct v4l2_subdev
*sd
;
1291 struct regmap
*regmap
;
1292 struct max2175
*ctx
;
1296 /* Parse DT properties */
1297 np
= of_parse_phandle(client
->dev
.of_node
, "maxim,master", 0);
1299 master
= false; /* Slave tuner */
1303 fwnode
= of_fwnode_handle(client
->dev
.of_node
);
1304 if (fwnode_property_present(fwnode
, "maxim,am-hiz-filter"))
1307 if (!fwnode_property_read_u32(fwnode
, "maxim,refout-load",
1309 ret
= max2175_refout_load_to_bits(client
, refout_load
,
1312 dev_err(&client
->dev
, "invalid refout_load %u\n",
1318 clk
= devm_clk_get(&client
->dev
, NULL
);
1321 dev_err(&client
->dev
, "cannot get clock %d\n", ret
);
1325 regmap
= devm_regmap_init_i2c(client
, &max2175_regmap_config
);
1326 if (IS_ERR(regmap
)) {
1327 ret
= PTR_ERR(regmap
);
1328 dev_err(&client
->dev
, "regmap init failed %d\n", ret
);
1332 /* Alloc tuner context */
1333 ctx
= devm_kzalloc(&client
->dev
, sizeof(*ctx
), GFP_KERNEL
);
1338 ctx
->master
= master
;
1339 ctx
->am_hiz
= am_hiz
;
1340 ctx
->mode_resolved
= false;
1341 ctx
->regmap
= regmap
;
1342 ctx
->xtal_freq
= clk_get_rate(clk
);
1343 dev_info(&client
->dev
, "xtal freq %luHz\n", ctx
->xtal_freq
);
1345 v4l2_i2c_subdev_init(sd
, client
, &max2175_ops
);
1346 ctx
->client
= client
;
1348 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
1351 hdl
= &ctx
->ctrl_hdl
;
1352 ret
= v4l2_ctrl_handler_init(hdl
, 7);
1356 ctx
->lna_gain
= v4l2_ctrl_new_std(hdl
, &max2175_ctrl_ops
,
1357 V4L2_CID_RF_TUNER_LNA_GAIN
,
1359 ctx
->lna_gain
->flags
|= (V4L2_CTRL_FLAG_VOLATILE
|
1360 V4L2_CTRL_FLAG_READ_ONLY
);
1361 ctx
->if_gain
= v4l2_ctrl_new_std(hdl
, &max2175_ctrl_ops
,
1362 V4L2_CID_RF_TUNER_IF_GAIN
,
1364 ctx
->if_gain
->flags
|= (V4L2_CTRL_FLAG_VOLATILE
|
1365 V4L2_CTRL_FLAG_READ_ONLY
);
1366 ctx
->pll_lock
= v4l2_ctrl_new_std(hdl
, &max2175_ctrl_ops
,
1367 V4L2_CID_RF_TUNER_PLL_LOCK
,
1369 ctx
->pll_lock
->flags
|= (V4L2_CTRL_FLAG_VOLATILE
|
1370 V4L2_CTRL_FLAG_READ_ONLY
);
1371 ctx
->i2s_en
= v4l2_ctrl_new_custom(hdl
, &max2175_i2s_en
, NULL
);
1372 ctx
->hsls
= v4l2_ctrl_new_custom(hdl
, &max2175_hsls
, NULL
);
1374 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
) {
1375 ctx
->rx_mode
= v4l2_ctrl_new_custom(hdl
,
1376 &max2175_eu_rx_mode
, NULL
);
1377 ctx
->rx_modes
= eu_rx_modes
;
1378 ctx
->bands_rf
= &eu_bands_rf
;
1380 ctx
->rx_mode
= v4l2_ctrl_new_custom(hdl
,
1381 &max2175_na_rx_mode
, NULL
);
1382 ctx
->rx_modes
= na_rx_modes
;
1383 ctx
->bands_rf
= &na_bands_rf
;
1385 ctx
->sd
.ctrl_handler
= &ctx
->ctrl_hdl
;
1387 /* Set the defaults */
1388 ctx
->freq
= ctx
->bands_rf
->rangelow
;
1390 /* Register subdev */
1391 ret
= v4l2_async_register_subdev(sd
);
1393 dev_err(&client
->dev
, "register subdev failed\n");
1397 /* Initialize device */
1398 ret
= max2175_core_init(ctx
, refout_bits
);
1402 ret
= v4l2_ctrl_handler_setup(hdl
);
1409 v4l2_async_unregister_subdev(sd
);
1411 v4l2_ctrl_handler_free(&ctx
->ctrl_hdl
);
1416 static int max2175_remove(struct i2c_client
*client
)
1418 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
1419 struct max2175
*ctx
= max2175_from_sd(sd
);
1421 v4l2_ctrl_handler_free(&ctx
->ctrl_hdl
);
1422 v4l2_async_unregister_subdev(sd
);
1427 static const struct i2c_device_id max2175_id
[] = {
1431 MODULE_DEVICE_TABLE(i2c
, max2175_id
);
1433 static const struct of_device_id max2175_of_ids
[] = {
1434 { .compatible
= "maxim,max2175", },
1437 MODULE_DEVICE_TABLE(of
, max2175_of_ids
);
1439 static struct i2c_driver max2175_driver
= {
1441 .name
= DRIVER_NAME
,
1442 .of_match_table
= max2175_of_ids
,
1444 .probe
= max2175_probe
,
1445 .remove
= max2175_remove
,
1446 .id_table
= max2175_id
,
1449 module_i2c_driver(max2175_driver
);
1451 MODULE_DESCRIPTION("Maxim MAX2175 RF to Bits tuner driver");
1452 MODULE_LICENSE("GPL v2");
1453 MODULE_AUTHOR("Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>");