1 // SPDX-License-Identifier: GPL-2.0
3 * Maxim Integrated MAX2175 RF to Bits tuner driver
5 * This driver & most of the hard coded values are based on the reference
6 * application delivered by Maxim for this device.
8 * Copyright (C) 2016 Maxim Integrated Products
9 * Copyright (C) 2017 Renesas Electronics Corporation
12 #include <linux/clk.h>
13 #include <linux/delay.h>
14 #include <linux/errno.h>
15 #include <linux/i2c.h>
16 #include <linux/kernel.h>
17 #include <linux/math64.h>
18 #include <linux/max2175.h>
19 #include <linux/module.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-device.h>
28 #define DRIVER_NAME "max2175"
30 #define mxm_dbg(ctx, fmt, arg...) dev_dbg(&ctx->client->dev, fmt, ## arg)
31 #define mxm_err(ctx, fmt, arg...) dev_err(&ctx->client->dev, fmt, ## arg)
34 struct max2175_rxmode
{
35 enum max2175_band band
; /* Associated band */
36 u32 freq
; /* Default freq in Hz */
37 u8 i2s_word_size
; /* Bit value */
40 /* Register map to define preset values */
41 struct max2175_reg_map
{
42 u8 idx
; /* Register index */
43 u8 val
; /* Register value */
46 static const struct max2175_rxmode eu_rx_modes
[] = {
48 [MAX2175_EU_FM_1_2
] = { MAX2175_BAND_FM
, 98256000, 1 },
49 [MAX2175_DAB_1_2
] = { MAX2175_BAND_VHF
, 182640000, 0 },
52 static const struct max2175_rxmode na_rx_modes
[] = {
54 [MAX2175_NA_FM_1_0
] = { MAX2175_BAND_FM
, 98255520, 1 },
55 [MAX2175_NA_FM_2_0
] = { MAX2175_BAND_FM
, 98255520, 6 },
60 * Based on Maxim MAX2175 Register Table revision: 130p10
62 static const u8 full_fm_eu_1p0
[] = {
63 0x15, 0x04, 0xb8, 0xe3, 0x35, 0x18, 0x7c, 0x00,
64 0x00, 0x7d, 0x40, 0x08, 0x70, 0x7a, 0x88, 0x91,
65 0x61, 0x61, 0x61, 0x61, 0x5a, 0x0f, 0x34, 0x1c,
66 0x14, 0x88, 0x33, 0x02, 0x00, 0x09, 0x00, 0x65,
67 0x9f, 0x2b, 0x80, 0x00, 0x95, 0x05, 0x2c, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
69 0x4a, 0x08, 0xa8, 0x0e, 0x0e, 0x2f, 0x7e, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x5e, 0xa9,
72 0xae, 0xbb, 0x57, 0x18, 0x3b, 0x03, 0x3b, 0x64,
73 0x40, 0x60, 0x00, 0x2a, 0xbf, 0x3f, 0xff, 0x9f,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
75 0xff, 0xfc, 0xef, 0x1c, 0x40, 0x00, 0x00, 0x02,
76 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x40, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
79 0x00, 0x47, 0x00, 0x00, 0x11, 0x3f, 0x22, 0x00,
80 0xf1, 0x00, 0x41, 0x03, 0xb0, 0x00, 0x00, 0x00,
84 static const u8 full_fm_na_1p0
[] = {
85 0x13, 0x08, 0x8d, 0xc0, 0x35, 0x18, 0x7d, 0x3f,
86 0x7d, 0x75, 0x40, 0x08, 0x70, 0x7a, 0x88, 0x91,
87 0x61, 0x61, 0x61, 0x61, 0x5c, 0x0f, 0x34, 0x1c,
88 0x14, 0x88, 0x33, 0x02, 0x00, 0x01, 0x00, 0x65,
89 0x9f, 0x2b, 0x80, 0x00, 0x95, 0x05, 0x2c, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
91 0x4a, 0x08, 0xa8, 0x0e, 0x0e, 0xaf, 0x7e, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x5e, 0xa9,
94 0xae, 0xbb, 0x57, 0x18, 0x3b, 0x03, 0x3b, 0x64,
95 0x40, 0x60, 0x00, 0x2a, 0xbf, 0x3f, 0xff, 0x9f,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
97 0xff, 0xfc, 0xef, 0x1c, 0x40, 0x00, 0x00, 0x02,
98 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x40, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
101 0x00, 0x35, 0x00, 0x00, 0x11, 0x3f, 0x22, 0x00,
102 0xf1, 0x00, 0x41, 0x03, 0xb0, 0x00, 0x00, 0x00,
106 /* DAB1.2 settings */
107 static const struct max2175_reg_map dab12_map
[] = {
108 { 0x01, 0x13 }, { 0x02, 0x0d }, { 0x03, 0x15 }, { 0x04, 0x55 },
109 { 0x05, 0x0a }, { 0x06, 0xa0 }, { 0x07, 0x40 }, { 0x08, 0x00 },
110 { 0x09, 0x00 }, { 0x0a, 0x7d }, { 0x0b, 0x4a }, { 0x0c, 0x28 },
111 { 0x0e, 0x43 }, { 0x0f, 0xb5 }, { 0x10, 0x31 }, { 0x11, 0x9e },
112 { 0x12, 0x68 }, { 0x13, 0x9e }, { 0x14, 0x68 }, { 0x15, 0x58 },
113 { 0x16, 0x2f }, { 0x17, 0x3f }, { 0x18, 0x40 }, { 0x1a, 0x88 },
114 { 0x1b, 0xaa }, { 0x1c, 0x9a }, { 0x1d, 0x00 }, { 0x1e, 0x00 },
115 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x00 }, { 0x26, 0x00 },
116 { 0x27, 0x00 }, { 0x32, 0x08 }, { 0x33, 0xf8 }, { 0x36, 0x2d },
117 { 0x37, 0x7e }, { 0x55, 0xaf }, { 0x56, 0x3f }, { 0x57, 0xf8 },
118 { 0x58, 0x99 }, { 0x76, 0x00 }, { 0x77, 0x00 }, { 0x78, 0x02 },
119 { 0x79, 0x40 }, { 0x82, 0x00 }, { 0x83, 0x00 }, { 0x85, 0x00 },
123 /* EU FM 1.2 settings */
124 static const struct max2175_reg_map fmeu1p2_map
[] = {
125 { 0x01, 0x15 }, { 0x02, 0x04 }, { 0x03, 0xb8 }, { 0x04, 0xe3 },
126 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7c }, { 0x08, 0x00 },
127 { 0x09, 0x00 }, { 0x0a, 0x73 }, { 0x0b, 0x40 }, { 0x0c, 0x08 },
128 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
129 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5a },
130 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
131 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
132 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
133 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0x2f },
134 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
135 { 0x58, 0x9f }, { 0x76, 0xac }, { 0x77, 0x40 }, { 0x78, 0x00 },
136 { 0x79, 0x00 }, { 0x82, 0x47 }, { 0x83, 0x00 }, { 0x85, 0x11 },
140 /* FM NA 1.0 settings */
141 static const struct max2175_reg_map fmna1p0_map
[] = {
142 { 0x01, 0x13 }, { 0x02, 0x08 }, { 0x03, 0x8d }, { 0x04, 0xc0 },
143 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7d }, { 0x08, 0x3f },
144 { 0x09, 0x7d }, { 0x0a, 0x75 }, { 0x0b, 0x40 }, { 0x0c, 0x08 },
145 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
146 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5c },
147 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
148 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
149 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
150 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0xaf },
151 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
152 { 0x58, 0x9f }, { 0x76, 0xa6 }, { 0x77, 0x40 }, { 0x78, 0x00 },
153 { 0x79, 0x00 }, { 0x82, 0x35 }, { 0x83, 0x00 }, { 0x85, 0x11 },
157 /* FM NA 2.0 settings */
158 static const struct max2175_reg_map fmna2p0_map
[] = {
159 { 0x01, 0x13 }, { 0x02, 0x08 }, { 0x03, 0x8d }, { 0x04, 0xc0 },
160 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7c }, { 0x08, 0x54 },
161 { 0x09, 0xa7 }, { 0x0a, 0x55 }, { 0x0b, 0x42 }, { 0x0c, 0x48 },
162 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
163 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5c },
164 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
165 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
166 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
167 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0xaf },
168 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
169 { 0x58, 0x9f }, { 0x76, 0xac }, { 0x77, 0xc0 }, { 0x78, 0x00 },
170 { 0x79, 0x00 }, { 0x82, 0x6b }, { 0x83, 0x00 }, { 0x85, 0x11 },
174 static const u16 ch_coeff_dab1
[] = {
175 0x001c, 0x0007, 0xffcd, 0x0056, 0xffa4, 0x0033, 0x0027, 0xff61,
176 0x010e, 0xfec0, 0x0106, 0xffb8, 0xff1c, 0x023c, 0xfcb2, 0x039b,
177 0xfd4e, 0x0055, 0x036a, 0xf7de, 0x0d21, 0xee72, 0x1499, 0x6a51,
180 static const u16 ch_coeff_fmeu
[] = {
181 0x0000, 0xffff, 0x0001, 0x0002, 0xfffa, 0xffff, 0x0015, 0xffec,
182 0xffde, 0x0054, 0xfff9, 0xff52, 0x00b8, 0x00a2, 0xfe0a, 0x00af,
183 0x02e3, 0xfc14, 0xfe89, 0x089d, 0xfa2e, 0xf30f, 0x25be, 0x4eb6,
186 static const u16 eq_coeff_fmeu1_ra02_m6db
[] = {
187 0x0040, 0xffc6, 0xfffa, 0x002c, 0x000d, 0xff90, 0x0037, 0x006e,
188 0xffc0, 0xff5b, 0x006a, 0x00f0, 0xff57, 0xfe94, 0x0112, 0x0252,
189 0xfe0c, 0xfc6a, 0x0385, 0x0553, 0xfa49, 0xf789, 0x0b91, 0x1a10,
192 static const u16 ch_coeff_fmna
[] = {
193 0x0001, 0x0003, 0xfffe, 0xfff4, 0x0000, 0x001f, 0x000c, 0xffbc,
194 0xffd3, 0x007d, 0x0075, 0xff33, 0xff01, 0x0131, 0x01ef, 0xfe60,
195 0xfc7a, 0x020e, 0x0656, 0xfd94, 0xf395, 0x02ab, 0x2857, 0x3d3f,
198 static const u16 eq_coeff_fmna1_ra02_m6db
[] = {
199 0xfff1, 0xffe1, 0xffef, 0x000e, 0x0030, 0x002f, 0xfff6, 0xffa7,
200 0xff9d, 0x000a, 0x00a2, 0x00b5, 0xffea, 0xfed9, 0xfec5, 0x003d,
201 0x0217, 0x021b, 0xff5a, 0xfc2b, 0xfcbd, 0x02c4, 0x0ac3, 0x0e85,
204 static const u8 adc_presets
[2][23] = {
206 0x83, 0x00, 0xcf, 0xb4, 0x0f, 0x2c, 0x0c, 0x49,
207 0x00, 0x00, 0x00, 0x8c, 0x02, 0x02, 0x00, 0x04,
208 0xec, 0x82, 0x4b, 0xcc, 0x01, 0x88, 0x0c,
211 0x83, 0x00, 0xcf, 0xb4, 0x0f, 0x2c, 0x0c, 0x49,
212 0x00, 0x00, 0x00, 0x8c, 0x02, 0x20, 0x33, 0x8c,
213 0x57, 0xd7, 0x59, 0xb7, 0x65, 0x0e, 0x0c,
218 static const struct v4l2_frequency_band eu_bands_rf
= {
220 .type
= V4L2_TUNER_RF
,
222 .capability
= V4L2_TUNER_CAP_1HZ
| V4L2_TUNER_CAP_FREQ_BANDS
,
223 .rangelow
= 65000000,
224 .rangehigh
= 240000000,
227 static const struct v4l2_frequency_band na_bands_rf
= {
229 .type
= V4L2_TUNER_RF
,
231 .capability
= V4L2_TUNER_CAP_1HZ
| V4L2_TUNER_CAP_FREQ_BANDS
,
232 .rangelow
= 65000000,
233 .rangehigh
= 108000000,
236 /* Regmap settings */
237 static const struct regmap_range max2175_regmap_volatile_range
[] = {
238 regmap_reg_range(0x30, 0x35),
239 regmap_reg_range(0x3a, 0x45),
240 regmap_reg_range(0x59, 0x5e),
241 regmap_reg_range(0x73, 0x75),
244 static const struct regmap_access_table max2175_volatile_regs
= {
245 .yes_ranges
= max2175_regmap_volatile_range
,
246 .n_yes_ranges
= ARRAY_SIZE(max2175_regmap_volatile_range
),
249 static const struct reg_default max2175_reg_defaults
[] = {
253 static const struct regmap_config max2175_regmap_config
= {
256 .max_register
= 0xff,
257 .reg_defaults
= max2175_reg_defaults
,
258 .num_reg_defaults
= ARRAY_SIZE(max2175_reg_defaults
),
259 .volatile_table
= &max2175_volatile_regs
,
260 .cache_type
= REGCACHE_MAPLE
,
264 struct v4l2_subdev sd
; /* Sub-device */
265 struct i2c_client
*client
; /* I2C client */
268 struct v4l2_ctrl_handler ctrl_hdl
;
269 struct v4l2_ctrl
*lna_gain
; /* LNA gain value */
270 struct v4l2_ctrl
*if_gain
; /* I/F gain value */
271 struct v4l2_ctrl
*pll_lock
; /* PLL lock */
272 struct v4l2_ctrl
*i2s_en
; /* I2S output enable */
273 struct v4l2_ctrl
*hsls
; /* High-side/Low-side polarity */
274 struct v4l2_ctrl
*rx_mode
; /* Receive mode */
277 struct regmap
*regmap
;
279 /* Cached configuration */
280 u32 freq
; /* Tuned freq In Hz */
281 const struct max2175_rxmode
*rx_modes
; /* EU or NA modes */
282 const struct v4l2_frequency_band
*bands_rf
; /* EU or NA bands */
284 /* Device settings */
285 unsigned long xtal_freq
; /* Ref Oscillator freq in Hz */
287 bool master
; /* Master/Slave */
288 bool am_hiz
; /* AM Hi-Z filter */
295 /* Driver private variables */
296 bool mode_resolved
; /* Flag to sanity check settings */
299 static inline struct max2175
*max2175_from_sd(struct v4l2_subdev
*sd
)
301 return container_of(sd
, struct max2175
, sd
);
304 static inline struct max2175
*max2175_from_ctrl_hdl(struct v4l2_ctrl_handler
*h
)
306 return container_of(h
, struct max2175
, ctrl_hdl
);
309 /* Get bitval of a given val */
310 static inline u8
max2175_get_bitval(u8 val
, u8 msb
, u8 lsb
)
312 return (val
& GENMASK(msb
, lsb
)) >> lsb
;
315 /* Read/Write bit(s) on top of regmap */
316 static int max2175_read(struct max2175
*ctx
, u8 idx
, u8
*val
)
321 ret
= regmap_read(ctx
->regmap
, idx
, ®val
);
323 mxm_err(ctx
, "read ret(%d): idx 0x%02x\n", ret
, idx
);
330 static int max2175_write(struct max2175
*ctx
, u8 idx
, u8 val
)
334 ret
= regmap_write(ctx
->regmap
, idx
, val
);
336 mxm_err(ctx
, "write ret(%d): idx 0x%02x val 0x%02x\n",
342 static u8
max2175_read_bits(struct max2175
*ctx
, u8 idx
, u8 msb
, u8 lsb
)
346 if (max2175_read(ctx
, idx
, &val
))
349 return max2175_get_bitval(val
, msb
, lsb
);
352 static int max2175_write_bits(struct max2175
*ctx
, u8 idx
,
353 u8 msb
, u8 lsb
, u8 newval
)
355 int ret
= regmap_update_bits(ctx
->regmap
, idx
, GENMASK(msb
, lsb
),
359 mxm_err(ctx
, "wbits ret(%d): idx 0x%02x\n", ret
, idx
);
364 static int max2175_write_bit(struct max2175
*ctx
, u8 idx
, u8 bit
, u8 newval
)
366 return max2175_write_bits(ctx
, idx
, bit
, bit
, newval
);
369 /* Checks expected pattern every msec until timeout */
370 static int max2175_poll_timeout(struct max2175
*ctx
, u8 idx
, u8 msb
, u8 lsb
,
371 u8 exp_bitval
, u32 timeout_us
)
375 return regmap_read_poll_timeout(ctx
->regmap
, idx
, val
,
376 (max2175_get_bitval(val
, msb
, lsb
) == exp_bitval
),
380 static int max2175_poll_csm_ready(struct max2175
*ctx
)
384 ret
= max2175_poll_timeout(ctx
, 69, 1, 1, 0, 50000);
386 mxm_err(ctx
, "csm not ready\n");
391 #define MAX2175_IS_BAND_AM(ctx) \
392 (max2175_read_bits(ctx, 5, 1, 0) == MAX2175_BAND_AM)
394 #define MAX2175_IS_BAND_VHF(ctx) \
395 (max2175_read_bits(ctx, 5, 1, 0) == MAX2175_BAND_VHF)
397 #define MAX2175_IS_FM_MODE(ctx) \
398 (max2175_read_bits(ctx, 12, 5, 4) == 0)
400 #define MAX2175_IS_FMHD_MODE(ctx) \
401 (max2175_read_bits(ctx, 12, 5, 4) == 1)
403 #define MAX2175_IS_DAB_MODE(ctx) \
404 (max2175_read_bits(ctx, 12, 5, 4) == 2)
406 static int max2175_band_from_freq(u32 freq
)
408 if (freq
>= 144000 && freq
<= 26100000)
409 return MAX2175_BAND_AM
;
410 else if (freq
>= 65000000 && freq
<= 108000000)
411 return MAX2175_BAND_FM
;
413 return MAX2175_BAND_VHF
;
416 static void max2175_i2s_enable(struct max2175
*ctx
, bool enable
)
419 /* Stuff bits are zeroed */
420 max2175_write_bits(ctx
, 104, 3, 0, 2);
423 max2175_write_bits(ctx
, 104, 3, 0, 9);
424 mxm_dbg(ctx
, "i2s %sabled\n", enable
? "en" : "dis");
427 static void max2175_set_filter_coeffs(struct max2175
*ctx
, u8 m_sel
,
428 u8 bank
, const u16
*coeffs
)
431 u8 coeff_addr
, upper_address
= 24;
433 mxm_dbg(ctx
, "set_filter_coeffs: m_sel %d bank %d\n", m_sel
, bank
);
434 max2175_write_bits(ctx
, 114, 5, 4, m_sel
);
439 for (i
= 0; i
< upper_address
; i
++) {
440 coeff_addr
= i
+ bank
* 24;
441 max2175_write(ctx
, 115, coeffs
[i
] >> 8);
442 max2175_write(ctx
, 116, coeffs
[i
]);
443 max2175_write(ctx
, 117, coeff_addr
| 1 << 7);
445 max2175_write_bit(ctx
, 117, 7, 0);
448 static void max2175_load_fmeu_1p2(struct max2175
*ctx
)
452 for (i
= 0; i
< ARRAY_SIZE(fmeu1p2_map
); i
++)
453 max2175_write(ctx
, fmeu1p2_map
[i
].idx
, fmeu1p2_map
[i
].val
);
455 ctx
->decim_ratio
= 36;
457 /* Load the Channel Filter Coefficients into channel filter bank #2 */
458 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0, ch_coeff_fmeu
);
459 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
460 eq_coeff_fmeu1_ra02_m6db
);
463 static void max2175_load_dab_1p2(struct max2175
*ctx
)
467 for (i
= 0; i
< ARRAY_SIZE(dab12_map
); i
++)
468 max2175_write(ctx
, dab12_map
[i
].idx
, dab12_map
[i
].val
);
470 ctx
->decim_ratio
= 1;
472 /* Load the Channel Filter Coefficients into channel filter bank #2 */
473 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 2, ch_coeff_dab1
);
476 static void max2175_load_fmna_1p0(struct max2175
*ctx
)
480 for (i
= 0; i
< ARRAY_SIZE(fmna1p0_map
); i
++)
481 max2175_write(ctx
, fmna1p0_map
[i
].idx
, fmna1p0_map
[i
].val
);
484 static void max2175_load_fmna_2p0(struct max2175
*ctx
)
488 for (i
= 0; i
< ARRAY_SIZE(fmna2p0_map
); i
++)
489 max2175_write(ctx
, fmna2p0_map
[i
].idx
, fmna2p0_map
[i
].val
);
492 static void max2175_set_bbfilter(struct max2175
*ctx
)
494 if (MAX2175_IS_BAND_AM(ctx
)) {
495 max2175_write_bits(ctx
, 12, 3, 0, ctx
->rom_bbf_bw_am
);
496 mxm_dbg(ctx
, "set_bbfilter AM: rom %d\n", ctx
->rom_bbf_bw_am
);
497 } else if (MAX2175_IS_DAB_MODE(ctx
)) {
498 max2175_write_bits(ctx
, 12, 3, 0, ctx
->rom_bbf_bw_dab
);
499 mxm_dbg(ctx
, "set_bbfilter DAB: rom %d\n", ctx
->rom_bbf_bw_dab
);
501 max2175_write_bits(ctx
, 12, 3, 0, ctx
->rom_bbf_bw_fm
);
502 mxm_dbg(ctx
, "set_bbfilter FM: rom %d\n", ctx
->rom_bbf_bw_fm
);
506 static int max2175_set_csm_mode(struct max2175
*ctx
,
507 enum max2175_csm_mode new_mode
)
509 int ret
= max2175_poll_csm_ready(ctx
);
514 max2175_write_bits(ctx
, 0, 2, 0, new_mode
);
515 mxm_dbg(ctx
, "set csm new mode %d\n", new_mode
);
517 /* Wait for a fixed settle down time depending on new mode */
519 case MAX2175_PRESET_TUNE
:
520 usleep_range(51100, 51500); /* 51.1ms */
523 * Other mode switches need different sleep values depending on band &
530 return max2175_poll_csm_ready(ctx
);
533 static int max2175_csm_action(struct max2175
*ctx
,
534 enum max2175_csm_mode action
)
538 mxm_dbg(ctx
, "csm_action: %d\n", action
);
540 /* Other actions can be added in future when needed */
541 ret
= max2175_set_csm_mode(ctx
, MAX2175_LOAD_TO_BUFFER
);
545 return max2175_set_csm_mode(ctx
, MAX2175_PRESET_TUNE
);
548 static int max2175_set_lo_freq(struct max2175
*ctx
, u32 lo_freq
)
550 u8 lo_mult
, loband_bits
= 0, vcodiv_bits
= 0;
551 u32 int_desired
, frac_desired
;
552 enum max2175_band band
;
555 band
= max2175_read_bits(ctx
, 5, 1, 0);
557 case MAX2175_BAND_AM
:
560 case MAX2175_BAND_FM
:
561 if (lo_freq
<= 74700000) {
563 } else if (lo_freq
> 74700000 && lo_freq
<= 110000000) {
572 case MAX2175_BAND_VHF
:
573 if (lo_freq
<= 210000000)
588 if (band
== MAX2175_BAND_L
)
593 int_desired
= lo_freq
/ ctx
->xtal_freq
;
594 frac_desired
= div64_ul((u64
)(lo_freq
% ctx
->xtal_freq
) << 20,
597 /* Check CSM is not busy */
598 ret
= max2175_poll_csm_ready(ctx
);
602 mxm_dbg(ctx
, "lo_mult %u int %u frac %u\n",
603 lo_mult
, int_desired
, frac_desired
);
605 /* Write the calculated values to the appropriate registers */
606 max2175_write(ctx
, 1, int_desired
);
607 max2175_write_bits(ctx
, 2, 3, 0, (frac_desired
>> 16) & 0xf);
608 max2175_write(ctx
, 3, frac_desired
>> 8);
609 max2175_write(ctx
, 4, frac_desired
);
610 max2175_write_bits(ctx
, 5, 3, 2, loband_bits
);
611 max2175_write_bits(ctx
, 6, 7, 6, vcodiv_bits
);
617 * Helper similar to DIV_ROUND_CLOSEST but an inline function that accepts s64
618 * dividend and s32 divisor
620 static inline s64
max2175_round_closest(s64 dividend
, s32 divisor
)
622 if ((dividend
> 0 && divisor
> 0) || (dividend
< 0 && divisor
< 0))
623 return div_s64(dividend
+ divisor
/ 2, divisor
);
625 return div_s64(dividend
- divisor
/ 2, divisor
);
628 static int max2175_set_nco_freq(struct max2175
*ctx
, s32 nco_freq
)
630 s32 clock_rate
= ctx
->xtal_freq
/ ctx
->decim_ratio
;
631 u32 nco_reg
, abs_nco_freq
= abs(nco_freq
);
635 if (abs_nco_freq
< clock_rate
/ 2) {
636 nco_val_desired
= 2 * nco_freq
;
638 nco_val_desired
= 2LL * (clock_rate
- abs_nco_freq
);
640 nco_val_desired
= -nco_val_desired
;
643 nco_reg
= max2175_round_closest(nco_val_desired
<< 20, clock_rate
);
648 /* Check CSM is not busy */
649 ret
= max2175_poll_csm_ready(ctx
);
653 mxm_dbg(ctx
, "freq %d desired %lld reg %u\n",
654 nco_freq
, nco_val_desired
, nco_reg
);
656 /* Write the calculated values to the appropriate registers */
657 max2175_write_bits(ctx
, 7, 4, 0, (nco_reg
>> 16) & 0x1f);
658 max2175_write(ctx
, 8, nco_reg
>> 8);
659 max2175_write(ctx
, 9, nco_reg
);
664 static int max2175_set_rf_freq_non_am_bands(struct max2175
*ctx
, u64 freq
,
667 s64 adj_freq
, low_if_freq
;
670 mxm_dbg(ctx
, "rf_freq: non AM bands\n");
672 if (MAX2175_IS_FM_MODE(ctx
))
673 low_if_freq
= 128000;
674 else if (MAX2175_IS_FMHD_MODE(ctx
))
675 low_if_freq
= 228000;
677 return max2175_set_lo_freq(ctx
, freq
);
679 if (MAX2175_IS_BAND_VHF(ctx
) == (lo_pos
== MAX2175_LO_ABOVE_DESIRED
))
680 adj_freq
= freq
+ low_if_freq
;
682 adj_freq
= freq
- low_if_freq
;
684 ret
= max2175_set_lo_freq(ctx
, adj_freq
);
688 return max2175_set_nco_freq(ctx
, -low_if_freq
);
691 static int max2175_set_rf_freq(struct max2175
*ctx
, u64 freq
, u32 lo_pos
)
695 if (MAX2175_IS_BAND_AM(ctx
))
696 ret
= max2175_set_nco_freq(ctx
, freq
);
698 ret
= max2175_set_rf_freq_non_am_bands(ctx
, freq
, lo_pos
);
700 mxm_dbg(ctx
, "set_rf_freq: ret %d freq %llu\n", ret
, freq
);
705 static int max2175_tune_rf_freq(struct max2175
*ctx
, u64 freq
, u32 hsls
)
709 ret
= max2175_set_rf_freq(ctx
, freq
, hsls
);
713 ret
= max2175_csm_action(ctx
, MAX2175_BUFFER_PLUS_PRESET_TUNE
);
717 mxm_dbg(ctx
, "tune_rf_freq: old %u new %llu\n", ctx
->freq
, freq
);
723 static void max2175_set_hsls(struct max2175
*ctx
, u32 lo_pos
)
725 mxm_dbg(ctx
, "set_hsls: lo_pos %u\n", lo_pos
);
727 if ((lo_pos
== MAX2175_LO_BELOW_DESIRED
) == MAX2175_IS_BAND_VHF(ctx
))
728 max2175_write_bit(ctx
, 5, 4, 1);
730 max2175_write_bit(ctx
, 5, 4, 0);
733 static void max2175_set_eu_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
736 case MAX2175_EU_FM_1_2
:
737 max2175_load_fmeu_1p2(ctx
);
740 case MAX2175_DAB_1_2
:
741 max2175_load_dab_1p2(ctx
);
744 /* Master is the default setting */
746 max2175_write_bit(ctx
, 30, 7, 1);
749 static void max2175_set_na_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
752 case MAX2175_NA_FM_1_0
:
753 max2175_load_fmna_1p0(ctx
);
755 case MAX2175_NA_FM_2_0
:
756 max2175_load_fmna_2p0(ctx
);
759 /* Master is the default setting */
761 max2175_write_bit(ctx
, 30, 7, 1);
763 ctx
->decim_ratio
= 27;
765 /* Load the Channel Filter Coefficients into channel filter bank #2 */
766 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0, ch_coeff_fmna
);
767 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
768 eq_coeff_fmna1_ra02_m6db
);
771 static int max2175_set_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
773 mxm_dbg(ctx
, "set_rx_mode: %u am_hiz %u\n", rx_mode
, ctx
->am_hiz
);
774 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
)
775 max2175_set_eu_rx_mode(ctx
, rx_mode
);
777 max2175_set_na_rx_mode(ctx
, rx_mode
);
780 mxm_dbg(ctx
, "setting AM HiZ related config\n");
781 max2175_write_bit(ctx
, 50, 5, 1);
782 max2175_write_bit(ctx
, 90, 7, 1);
783 max2175_write_bits(ctx
, 73, 1, 0, 2);
784 max2175_write_bits(ctx
, 80, 5, 0, 33);
787 /* Load BB filter trim values saved in ROM */
788 max2175_set_bbfilter(ctx
);
791 max2175_set_hsls(ctx
, ctx
->hsls
->cur
.val
);
793 /* Use i2s enable settings */
794 max2175_i2s_enable(ctx
, ctx
->i2s_en
->cur
.val
);
796 ctx
->mode_resolved
= true;
801 static int max2175_rx_mode_from_freq(struct max2175
*ctx
, u32 freq
, u32
*mode
)
804 int band
= max2175_band_from_freq(freq
);
806 /* Pick the first match always */
807 for (i
= 0; i
<= ctx
->rx_mode
->maximum
; i
++) {
808 if (ctx
->rx_modes
[i
].band
== band
) {
810 mxm_dbg(ctx
, "rx_mode_from_freq: freq %u mode %d\n",
819 static bool max2175_freq_rx_mode_valid(struct max2175
*ctx
,
822 int band
= max2175_band_from_freq(freq
);
824 return (ctx
->rx_modes
[mode
].band
== band
);
827 static void max2175_load_adc_presets(struct max2175
*ctx
)
831 for (i
= 0; i
< ARRAY_SIZE(adc_presets
); i
++)
832 for (j
= 0; j
< ARRAY_SIZE(adc_presets
[0]); j
++)
833 max2175_write(ctx
, 146 + j
+ i
* 55, adc_presets
[i
][j
]);
836 static int max2175_init_power_manager(struct max2175
*ctx
)
840 /* Execute on-chip power-up/calibration */
841 max2175_write_bit(ctx
, 99, 2, 0);
842 usleep_range(1000, 1500);
843 max2175_write_bit(ctx
, 99, 2, 1);
845 /* Wait for the power manager to finish. */
846 ret
= max2175_poll_timeout(ctx
, 69, 7, 7, 1, 50000);
848 mxm_err(ctx
, "init pm failed\n");
853 static int max2175_recalibrate_adc(struct max2175
*ctx
)
857 /* ADC Re-calibration */
858 max2175_write(ctx
, 150, 0xff);
859 max2175_write(ctx
, 205, 0xff);
860 max2175_write(ctx
, 147, 0x20);
861 max2175_write(ctx
, 147, 0x00);
862 max2175_write(ctx
, 202, 0x20);
863 max2175_write(ctx
, 202, 0x00);
865 ret
= max2175_poll_timeout(ctx
, 69, 4, 3, 3, 50000);
867 mxm_err(ctx
, "adc recalibration failed\n");
872 static u8
max2175_read_rom(struct max2175
*ctx
, u8 row
)
876 max2175_write_bit(ctx
, 56, 4, 0);
877 max2175_write_bits(ctx
, 56, 3, 0, row
);
879 usleep_range(2000, 2500);
880 max2175_read(ctx
, 58, &data
);
882 max2175_write_bits(ctx
, 56, 3, 0, 0);
884 mxm_dbg(ctx
, "read_rom: row %d data 0x%02x\n", row
, data
);
889 static void max2175_load_from_rom(struct max2175
*ctx
)
893 data
= max2175_read_rom(ctx
, 0);
894 ctx
->rom_bbf_bw_am
= data
& 0x0f;
895 max2175_write_bits(ctx
, 81, 3, 0, data
>> 4);
897 data
= max2175_read_rom(ctx
, 1);
898 ctx
->rom_bbf_bw_fm
= data
& 0x0f;
899 ctx
->rom_bbf_bw_dab
= data
>> 4;
901 data
= max2175_read_rom(ctx
, 2);
902 max2175_write_bits(ctx
, 82, 4, 0, data
& 0x1f);
903 max2175_write_bits(ctx
, 82, 7, 5, data
>> 5);
905 data
= max2175_read_rom(ctx
, 3);
908 data
|= (max2175_read_rom(ctx
, 7) & 0x40) >> 2;
912 data
= (data
& 0xf0) >> 4;
913 data
|= (max2175_read_rom(ctx
, 7) & 0x80) >> 3;
917 max2175_write_bits(ctx
, 80, 5, 0, data
+ 31);
919 data
= max2175_read_rom(ctx
, 6);
920 max2175_write_bits(ctx
, 81, 7, 6, data
>> 6);
923 static void max2175_load_full_fm_eu_1p0(struct max2175
*ctx
)
927 for (i
= 0; i
< ARRAY_SIZE(full_fm_eu_1p0
); i
++)
928 max2175_write(ctx
, i
+ 1, full_fm_eu_1p0
[i
]);
930 usleep_range(5000, 5500);
931 ctx
->decim_ratio
= 36;
934 static void max2175_load_full_fm_na_1p0(struct max2175
*ctx
)
938 for (i
= 0; i
< ARRAY_SIZE(full_fm_na_1p0
); i
++)
939 max2175_write(ctx
, i
+ 1, full_fm_na_1p0
[i
]);
941 usleep_range(5000, 5500);
942 ctx
->decim_ratio
= 27;
945 static int max2175_core_init(struct max2175
*ctx
, u32 refout_bits
)
949 /* MAX2175 uses 36.864MHz clock for EU & 40.154MHz for NA region */
950 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
)
951 max2175_load_full_fm_eu_1p0(ctx
);
953 max2175_load_full_fm_na_1p0(ctx
);
955 /* The default settings assume master */
957 max2175_write_bit(ctx
, 30, 7, 1);
959 mxm_dbg(ctx
, "refout_bits %u\n", refout_bits
);
962 max2175_write_bits(ctx
, 56, 7, 5, refout_bits
);
965 max2175_write_bit(ctx
, 99, 1, 0);
966 usleep_range(1000, 1500);
967 max2175_write_bit(ctx
, 99, 1, 1);
969 /* Load ADC preset values */
970 max2175_load_adc_presets(ctx
);
972 /* Initialize the power management state machine */
973 ret
= max2175_init_power_manager(ctx
);
977 /* Recalibrate ADC */
978 ret
= max2175_recalibrate_adc(ctx
);
982 /* Load ROM values to appropriate registers */
983 max2175_load_from_rom(ctx
);
985 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
) {
986 /* Load FIR coefficients into bank 0 */
987 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0,
989 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
990 eq_coeff_fmeu1_ra02_m6db
);
992 /* Load FIR coefficients into bank 0 */
993 max2175_set_filter_coeffs(ctx
, MAX2175_CH_MSEL
, 0,
995 max2175_set_filter_coeffs(ctx
, MAX2175_EQ_MSEL
, 0,
996 eq_coeff_fmna1_ra02_m6db
);
998 mxm_dbg(ctx
, "core initialized\n");
1003 static void max2175_s_ctrl_rx_mode(struct max2175
*ctx
, u32 rx_mode
)
1005 /* Load mode. Range check already done */
1006 max2175_set_rx_mode(ctx
, rx_mode
);
1008 mxm_dbg(ctx
, "s_ctrl_rx_mode: %u curr freq %u\n", rx_mode
, ctx
->freq
);
1010 /* Check if current freq valid for mode & update */
1011 if (max2175_freq_rx_mode_valid(ctx
, rx_mode
, ctx
->freq
))
1012 max2175_tune_rf_freq(ctx
, ctx
->freq
, ctx
->hsls
->cur
.val
);
1014 /* Use default freq of mode if current freq is not valid */
1015 max2175_tune_rf_freq(ctx
, ctx
->rx_modes
[rx_mode
].freq
,
1016 ctx
->hsls
->cur
.val
);
1019 static int max2175_s_ctrl(struct v4l2_ctrl
*ctrl
)
1021 struct max2175
*ctx
= max2175_from_ctrl_hdl(ctrl
->handler
);
1023 mxm_dbg(ctx
, "s_ctrl: id 0x%x, val %u\n", ctrl
->id
, ctrl
->val
);
1025 case V4L2_CID_MAX2175_I2S_ENABLE
:
1026 max2175_i2s_enable(ctx
, ctrl
->val
);
1028 case V4L2_CID_MAX2175_HSLS
:
1029 max2175_set_hsls(ctx
, ctrl
->val
);
1031 case V4L2_CID_MAX2175_RX_MODE
:
1032 max2175_s_ctrl_rx_mode(ctx
, ctrl
->val
);
1039 static u32
max2175_get_lna_gain(struct max2175
*ctx
)
1041 enum max2175_band band
= max2175_read_bits(ctx
, 5, 1, 0);
1044 case MAX2175_BAND_AM
:
1045 return max2175_read_bits(ctx
, 51, 3, 0);
1046 case MAX2175_BAND_FM
:
1047 return max2175_read_bits(ctx
, 50, 3, 0);
1048 case MAX2175_BAND_VHF
:
1049 return max2175_read_bits(ctx
, 52, 5, 0);
1055 static int max2175_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
1057 struct max2175
*ctx
= max2175_from_ctrl_hdl(ctrl
->handler
);
1060 case V4L2_CID_RF_TUNER_LNA_GAIN
:
1061 ctrl
->val
= max2175_get_lna_gain(ctx
);
1063 case V4L2_CID_RF_TUNER_IF_GAIN
:
1064 ctrl
->val
= max2175_read_bits(ctx
, 49, 4, 0);
1066 case V4L2_CID_RF_TUNER_PLL_LOCK
:
1067 ctrl
->val
= (max2175_read_bits(ctx
, 60, 7, 6) == 3);
1074 static int max2175_set_freq_and_mode(struct max2175
*ctx
, u32 freq
)
1079 /* Get band from frequency */
1080 ret
= max2175_rx_mode_from_freq(ctx
, freq
, &rx_mode
);
1084 mxm_dbg(ctx
, "set_freq_and_mode: freq %u rx_mode %d\n", freq
, rx_mode
);
1087 max2175_set_rx_mode(ctx
, rx_mode
);
1088 ctx
->rx_mode
->cur
.val
= rx_mode
;
1090 /* Tune to the new freq given */
1091 return max2175_tune_rf_freq(ctx
, freq
, ctx
->hsls
->cur
.val
);
1094 static int max2175_s_frequency(struct v4l2_subdev
*sd
,
1095 const struct v4l2_frequency
*vf
)
1097 struct max2175
*ctx
= max2175_from_sd(sd
);
1101 mxm_dbg(ctx
, "s_freq: new %u curr %u, mode_resolved %d\n",
1102 vf
->frequency
, ctx
->freq
, ctx
->mode_resolved
);
1107 freq
= clamp(vf
->frequency
, ctx
->bands_rf
->rangelow
,
1108 ctx
->bands_rf
->rangehigh
);
1110 /* Check new freq valid for rx_mode if already resolved */
1111 if (ctx
->mode_resolved
&&
1112 max2175_freq_rx_mode_valid(ctx
, ctx
->rx_mode
->cur
.val
, freq
))
1113 ret
= max2175_tune_rf_freq(ctx
, freq
, ctx
->hsls
->cur
.val
);
1115 /* Find default rx_mode for freq and tune to it */
1116 ret
= max2175_set_freq_and_mode(ctx
, freq
);
1118 mxm_dbg(ctx
, "s_freq: ret %d curr %u mode_resolved %d mode %u\n",
1119 ret
, ctx
->freq
, ctx
->mode_resolved
, ctx
->rx_mode
->cur
.val
);
1124 static int max2175_g_frequency(struct v4l2_subdev
*sd
,
1125 struct v4l2_frequency
*vf
)
1127 struct max2175
*ctx
= max2175_from_sd(sd
);
1133 vf
->type
= V4L2_TUNER_RF
;
1134 vf
->frequency
= ctx
->freq
;
1139 static int max2175_enum_freq_bands(struct v4l2_subdev
*sd
,
1140 struct v4l2_frequency_band
*band
)
1142 struct max2175
*ctx
= max2175_from_sd(sd
);
1144 if (band
->tuner
!= 0 || band
->index
!= 0)
1147 *band
= *ctx
->bands_rf
;
1152 static int max2175_g_tuner(struct v4l2_subdev
*sd
, struct v4l2_tuner
*vt
)
1154 struct max2175
*ctx
= max2175_from_sd(sd
);
1159 strscpy(vt
->name
, "RF", sizeof(vt
->name
));
1160 vt
->type
= V4L2_TUNER_RF
;
1161 vt
->capability
= V4L2_TUNER_CAP_1HZ
| V4L2_TUNER_CAP_FREQ_BANDS
;
1162 vt
->rangelow
= ctx
->bands_rf
->rangelow
;
1163 vt
->rangehigh
= ctx
->bands_rf
->rangehigh
;
1168 static int max2175_s_tuner(struct v4l2_subdev
*sd
, const struct v4l2_tuner
*vt
)
1170 /* Check tuner index is valid */
1177 static const struct v4l2_subdev_tuner_ops max2175_tuner_ops
= {
1178 .s_frequency
= max2175_s_frequency
,
1179 .g_frequency
= max2175_g_frequency
,
1180 .enum_freq_bands
= max2175_enum_freq_bands
,
1181 .g_tuner
= max2175_g_tuner
,
1182 .s_tuner
= max2175_s_tuner
,
1185 static const struct v4l2_subdev_ops max2175_ops
= {
1186 .tuner
= &max2175_tuner_ops
,
1189 static const struct v4l2_ctrl_ops max2175_ctrl_ops
= {
1190 .s_ctrl
= max2175_s_ctrl
,
1191 .g_volatile_ctrl
= max2175_g_volatile_ctrl
,
1195 * I2S output enable/disable configuration. This is a private control.
1196 * Refer to Documentation/userspace-api/media/drivers/max2175.rst for more details.
1198 static const struct v4l2_ctrl_config max2175_i2s_en
= {
1199 .ops
= &max2175_ctrl_ops
,
1200 .id
= V4L2_CID_MAX2175_I2S_ENABLE
,
1201 .name
= "I2S Enable",
1202 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1211 * HSLS value control LO freq adjacent location configuration.
1212 * Refer to Documentation/userspace-api/media/drivers/max2175.rst for more details.
1214 static const struct v4l2_ctrl_config max2175_hsls
= {
1215 .ops
= &max2175_ctrl_ops
,
1216 .id
= V4L2_CID_MAX2175_HSLS
,
1217 .name
= "HSLS Above/Below Desired",
1218 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
1226 * Rx modes below are a set of preset configurations that decides the tuner's
1227 * sck and sample rate of transmission. They are separate for EU & NA regions.
1228 * Refer to Documentation/userspace-api/media/drivers/max2175.rst for more details.
1230 static const char * const max2175_ctrl_eu_rx_modes
[] = {
1231 [MAX2175_EU_FM_1_2
] = "EU FM 1.2",
1232 [MAX2175_DAB_1_2
] = "DAB 1.2",
1235 static const char * const max2175_ctrl_na_rx_modes
[] = {
1236 [MAX2175_NA_FM_1_0
] = "NA FM 1.0",
1237 [MAX2175_NA_FM_2_0
] = "NA FM 2.0",
1240 static const struct v4l2_ctrl_config max2175_eu_rx_mode
= {
1241 .ops
= &max2175_ctrl_ops
,
1242 .id
= V4L2_CID_MAX2175_RX_MODE
,
1244 .type
= V4L2_CTRL_TYPE_MENU
,
1245 .max
= ARRAY_SIZE(max2175_ctrl_eu_rx_modes
) - 1,
1247 .qmenu
= max2175_ctrl_eu_rx_modes
,
1250 static const struct v4l2_ctrl_config max2175_na_rx_mode
= {
1251 .ops
= &max2175_ctrl_ops
,
1252 .id
= V4L2_CID_MAX2175_RX_MODE
,
1254 .type
= V4L2_CTRL_TYPE_MENU
,
1255 .max
= ARRAY_SIZE(max2175_ctrl_na_rx_modes
) - 1,
1257 .qmenu
= max2175_ctrl_na_rx_modes
,
1260 static int max2175_refout_load_to_bits(struct i2c_client
*client
, u32 load
,
1265 else if (load
>= 60 && load
<= 70)
1266 *bits
= load
/ 10 - 1;
1273 static int max2175_probe(struct i2c_client
*client
)
1275 bool master
= true, am_hiz
= false;
1276 u32 refout_load
, refout_bits
= 0; /* REFOUT disabled */
1277 struct v4l2_ctrl_handler
*hdl
;
1278 struct fwnode_handle
*fwnode
;
1279 struct device_node
*np
;
1280 struct v4l2_subdev
*sd
;
1281 struct regmap
*regmap
;
1282 struct max2175
*ctx
;
1286 /* Parse DT properties */
1287 np
= of_parse_phandle(client
->dev
.of_node
, "maxim,master", 0);
1289 master
= false; /* Slave tuner */
1293 fwnode
= of_fwnode_handle(client
->dev
.of_node
);
1294 if (fwnode_property_present(fwnode
, "maxim,am-hiz-filter"))
1297 if (!fwnode_property_read_u32(fwnode
, "maxim,refout-load",
1299 ret
= max2175_refout_load_to_bits(client
, refout_load
,
1302 dev_err(&client
->dev
, "invalid refout_load %u\n",
1308 clk
= devm_clk_get(&client
->dev
, NULL
);
1311 dev_err(&client
->dev
, "cannot get clock %d\n", ret
);
1315 regmap
= devm_regmap_init_i2c(client
, &max2175_regmap_config
);
1316 if (IS_ERR(regmap
)) {
1317 ret
= PTR_ERR(regmap
);
1318 dev_err(&client
->dev
, "regmap init failed %d\n", ret
);
1322 /* Alloc tuner context */
1323 ctx
= devm_kzalloc(&client
->dev
, sizeof(*ctx
), GFP_KERNEL
);
1328 ctx
->master
= master
;
1329 ctx
->am_hiz
= am_hiz
;
1330 ctx
->mode_resolved
= false;
1331 ctx
->regmap
= regmap
;
1332 ctx
->xtal_freq
= clk_get_rate(clk
);
1333 dev_info(&client
->dev
, "xtal freq %luHz\n", ctx
->xtal_freq
);
1335 v4l2_i2c_subdev_init(sd
, client
, &max2175_ops
);
1336 ctx
->client
= client
;
1338 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
1341 hdl
= &ctx
->ctrl_hdl
;
1342 ret
= v4l2_ctrl_handler_init(hdl
, 7);
1346 ctx
->lna_gain
= v4l2_ctrl_new_std(hdl
, &max2175_ctrl_ops
,
1347 V4L2_CID_RF_TUNER_LNA_GAIN
,
1349 ctx
->lna_gain
->flags
|= (V4L2_CTRL_FLAG_VOLATILE
|
1350 V4L2_CTRL_FLAG_READ_ONLY
);
1351 ctx
->if_gain
= v4l2_ctrl_new_std(hdl
, &max2175_ctrl_ops
,
1352 V4L2_CID_RF_TUNER_IF_GAIN
,
1354 ctx
->if_gain
->flags
|= (V4L2_CTRL_FLAG_VOLATILE
|
1355 V4L2_CTRL_FLAG_READ_ONLY
);
1356 ctx
->pll_lock
= v4l2_ctrl_new_std(hdl
, &max2175_ctrl_ops
,
1357 V4L2_CID_RF_TUNER_PLL_LOCK
,
1359 ctx
->pll_lock
->flags
|= (V4L2_CTRL_FLAG_VOLATILE
|
1360 V4L2_CTRL_FLAG_READ_ONLY
);
1361 ctx
->i2s_en
= v4l2_ctrl_new_custom(hdl
, &max2175_i2s_en
, NULL
);
1362 ctx
->hsls
= v4l2_ctrl_new_custom(hdl
, &max2175_hsls
, NULL
);
1364 if (ctx
->xtal_freq
== MAX2175_EU_XTAL_FREQ
) {
1365 ctx
->rx_mode
= v4l2_ctrl_new_custom(hdl
,
1366 &max2175_eu_rx_mode
, NULL
);
1367 ctx
->rx_modes
= eu_rx_modes
;
1368 ctx
->bands_rf
= &eu_bands_rf
;
1370 ctx
->rx_mode
= v4l2_ctrl_new_custom(hdl
,
1371 &max2175_na_rx_mode
, NULL
);
1372 ctx
->rx_modes
= na_rx_modes
;
1373 ctx
->bands_rf
= &na_bands_rf
;
1375 ctx
->sd
.ctrl_handler
= &ctx
->ctrl_hdl
;
1377 /* Set the defaults */
1378 ctx
->freq
= ctx
->bands_rf
->rangelow
;
1380 /* Register subdev */
1381 ret
= v4l2_async_register_subdev(sd
);
1383 dev_err(&client
->dev
, "register subdev failed\n");
1387 /* Initialize device */
1388 ret
= max2175_core_init(ctx
, refout_bits
);
1392 ret
= v4l2_ctrl_handler_setup(hdl
);
1399 v4l2_async_unregister_subdev(sd
);
1401 v4l2_ctrl_handler_free(&ctx
->ctrl_hdl
);
1406 static void max2175_remove(struct i2c_client
*client
)
1408 struct v4l2_subdev
*sd
= i2c_get_clientdata(client
);
1409 struct max2175
*ctx
= max2175_from_sd(sd
);
1411 v4l2_ctrl_handler_free(&ctx
->ctrl_hdl
);
1412 v4l2_async_unregister_subdev(sd
);
1415 static const struct i2c_device_id max2175_id
[] = {
1419 MODULE_DEVICE_TABLE(i2c
, max2175_id
);
1421 static const struct of_device_id max2175_of_ids
[] = {
1422 { .compatible
= "maxim,max2175", },
1425 MODULE_DEVICE_TABLE(of
, max2175_of_ids
);
1427 static struct i2c_driver max2175_driver
= {
1429 .name
= DRIVER_NAME
,
1430 .of_match_table
= max2175_of_ids
,
1432 .probe
= max2175_probe
,
1433 .remove
= max2175_remove
,
1434 .id_table
= max2175_id
,
1437 module_i2c_driver(max2175_driver
);
1439 MODULE_DESCRIPTION("Maxim MAX2175 RF to Bits tuner driver");
1440 MODULE_LICENSE("GPL v2");
1441 MODULE_AUTHOR("Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>");