0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/clk.h>
0013 #include <linux/delay.h>
0014 #include <linux/errno.h>
0015 #include <linux/i2c.h>
0016 #include <linux/kernel.h>
0017 #include <linux/math64.h>
0018 #include <linux/max2175.h>
0019 #include <linux/module.h>
0020 #include <linux/of.h>
0021 #include <linux/regmap.h>
0022 #include <linux/slab.h>
0023 #include <media/v4l2-ctrls.h>
0024 #include <media/v4l2-device.h>
0025
0026 #include "max2175.h"
0027
0028 #define DRIVER_NAME "max2175"
0029
0030 #define mxm_dbg(ctx, fmt, arg...) dev_dbg(&ctx->client->dev, fmt, ## arg)
0031 #define mxm_err(ctx, fmt, arg...) dev_err(&ctx->client->dev, fmt, ## arg)
0032
0033
0034 struct max2175_rxmode {
0035 enum max2175_band band;
0036 u32 freq;
0037 u8 i2s_word_size;
0038 };
0039
0040
0041 struct max2175_reg_map {
0042 u8 idx;
0043 u8 val;
0044 };
0045
0046 static const struct max2175_rxmode eu_rx_modes[] = {
0047
0048 [MAX2175_EU_FM_1_2] = { MAX2175_BAND_FM, 98256000, 1 },
0049 [MAX2175_DAB_1_2] = { MAX2175_BAND_VHF, 182640000, 0 },
0050 };
0051
0052 static const struct max2175_rxmode na_rx_modes[] = {
0053
0054 [MAX2175_NA_FM_1_0] = { MAX2175_BAND_FM, 98255520, 1 },
0055 [MAX2175_NA_FM_2_0] = { MAX2175_BAND_FM, 98255520, 6 },
0056 };
0057
0058
0059
0060
0061
0062 static const u8 full_fm_eu_1p0[] = {
0063 0x15, 0x04, 0xb8, 0xe3, 0x35, 0x18, 0x7c, 0x00,
0064 0x00, 0x7d, 0x40, 0x08, 0x70, 0x7a, 0x88, 0x91,
0065 0x61, 0x61, 0x61, 0x61, 0x5a, 0x0f, 0x34, 0x1c,
0066 0x14, 0x88, 0x33, 0x02, 0x00, 0x09, 0x00, 0x65,
0067 0x9f, 0x2b, 0x80, 0x00, 0x95, 0x05, 0x2c, 0x00,
0068 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0069 0x4a, 0x08, 0xa8, 0x0e, 0x0e, 0x2f, 0x7e, 0x00,
0070 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0071 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x5e, 0xa9,
0072 0xae, 0xbb, 0x57, 0x18, 0x3b, 0x03, 0x3b, 0x64,
0073 0x40, 0x60, 0x00, 0x2a, 0xbf, 0x3f, 0xff, 0x9f,
0074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
0075 0xff, 0xfc, 0xef, 0x1c, 0x40, 0x00, 0x00, 0x02,
0076 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0077 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x40, 0x00,
0078 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
0079 0x00, 0x47, 0x00, 0x00, 0x11, 0x3f, 0x22, 0x00,
0080 0xf1, 0x00, 0x41, 0x03, 0xb0, 0x00, 0x00, 0x00,
0081 0x1b,
0082 };
0083
0084 static const u8 full_fm_na_1p0[] = {
0085 0x13, 0x08, 0x8d, 0xc0, 0x35, 0x18, 0x7d, 0x3f,
0086 0x7d, 0x75, 0x40, 0x08, 0x70, 0x7a, 0x88, 0x91,
0087 0x61, 0x61, 0x61, 0x61, 0x5c, 0x0f, 0x34, 0x1c,
0088 0x14, 0x88, 0x33, 0x02, 0x00, 0x01, 0x00, 0x65,
0089 0x9f, 0x2b, 0x80, 0x00, 0x95, 0x05, 0x2c, 0x00,
0090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
0091 0x4a, 0x08, 0xa8, 0x0e, 0x0e, 0xaf, 0x7e, 0x00,
0092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0093 0x00, 0x00, 0x00, 0x00, 0x00, 0xab, 0x5e, 0xa9,
0094 0xae, 0xbb, 0x57, 0x18, 0x3b, 0x03, 0x3b, 0x64,
0095 0x40, 0x60, 0x00, 0x2a, 0xbf, 0x3f, 0xff, 0x9f,
0096 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
0097 0xff, 0xfc, 0xef, 0x1c, 0x40, 0x00, 0x00, 0x02,
0098 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0099 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x40, 0x00,
0100 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00,
0101 0x00, 0x35, 0x00, 0x00, 0x11, 0x3f, 0x22, 0x00,
0102 0xf1, 0x00, 0x41, 0x03, 0xb0, 0x00, 0x00, 0x00,
0103 0x1b,
0104 };
0105
0106
0107 static const struct max2175_reg_map dab12_map[] = {
0108 { 0x01, 0x13 }, { 0x02, 0x0d }, { 0x03, 0x15 }, { 0x04, 0x55 },
0109 { 0x05, 0x0a }, { 0x06, 0xa0 }, { 0x07, 0x40 }, { 0x08, 0x00 },
0110 { 0x09, 0x00 }, { 0x0a, 0x7d }, { 0x0b, 0x4a }, { 0x0c, 0x28 },
0111 { 0x0e, 0x43 }, { 0x0f, 0xb5 }, { 0x10, 0x31 }, { 0x11, 0x9e },
0112 { 0x12, 0x68 }, { 0x13, 0x9e }, { 0x14, 0x68 }, { 0x15, 0x58 },
0113 { 0x16, 0x2f }, { 0x17, 0x3f }, { 0x18, 0x40 }, { 0x1a, 0x88 },
0114 { 0x1b, 0xaa }, { 0x1c, 0x9a }, { 0x1d, 0x00 }, { 0x1e, 0x00 },
0115 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x00 }, { 0x26, 0x00 },
0116 { 0x27, 0x00 }, { 0x32, 0x08 }, { 0x33, 0xf8 }, { 0x36, 0x2d },
0117 { 0x37, 0x7e }, { 0x55, 0xaf }, { 0x56, 0x3f }, { 0x57, 0xf8 },
0118 { 0x58, 0x99 }, { 0x76, 0x00 }, { 0x77, 0x00 }, { 0x78, 0x02 },
0119 { 0x79, 0x40 }, { 0x82, 0x00 }, { 0x83, 0x00 }, { 0x85, 0x00 },
0120 { 0x86, 0x20 },
0121 };
0122
0123
0124 static const struct max2175_reg_map fmeu1p2_map[] = {
0125 { 0x01, 0x15 }, { 0x02, 0x04 }, { 0x03, 0xb8 }, { 0x04, 0xe3 },
0126 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7c }, { 0x08, 0x00 },
0127 { 0x09, 0x00 }, { 0x0a, 0x73 }, { 0x0b, 0x40 }, { 0x0c, 0x08 },
0128 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
0129 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5a },
0130 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
0131 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
0132 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
0133 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0x2f },
0134 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
0135 { 0x58, 0x9f }, { 0x76, 0xac }, { 0x77, 0x40 }, { 0x78, 0x00 },
0136 { 0x79, 0x00 }, { 0x82, 0x47 }, { 0x83, 0x00 }, { 0x85, 0x11 },
0137 { 0x86, 0x3f },
0138 };
0139
0140
0141 static const struct max2175_reg_map fmna1p0_map[] = {
0142 { 0x01, 0x13 }, { 0x02, 0x08 }, { 0x03, 0x8d }, { 0x04, 0xc0 },
0143 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7d }, { 0x08, 0x3f },
0144 { 0x09, 0x7d }, { 0x0a, 0x75 }, { 0x0b, 0x40 }, { 0x0c, 0x08 },
0145 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
0146 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5c },
0147 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
0148 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
0149 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
0150 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0xaf },
0151 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
0152 { 0x58, 0x9f }, { 0x76, 0xa6 }, { 0x77, 0x40 }, { 0x78, 0x00 },
0153 { 0x79, 0x00 }, { 0x82, 0x35 }, { 0x83, 0x00 }, { 0x85, 0x11 },
0154 { 0x86, 0x3f },
0155 };
0156
0157
0158 static const struct max2175_reg_map fmna2p0_map[] = {
0159 { 0x01, 0x13 }, { 0x02, 0x08 }, { 0x03, 0x8d }, { 0x04, 0xc0 },
0160 { 0x05, 0x35 }, { 0x06, 0x18 }, { 0x07, 0x7c }, { 0x08, 0x54 },
0161 { 0x09, 0xa7 }, { 0x0a, 0x55 }, { 0x0b, 0x42 }, { 0x0c, 0x48 },
0162 { 0x0e, 0x7a }, { 0x0f, 0x88 }, { 0x10, 0x91 }, { 0x11, 0x61 },
0163 { 0x12, 0x61 }, { 0x13, 0x61 }, { 0x14, 0x61 }, { 0x15, 0x5c },
0164 { 0x16, 0x0f }, { 0x17, 0x34 }, { 0x18, 0x1c }, { 0x1a, 0x88 },
0165 { 0x1b, 0x33 }, { 0x1c, 0x02 }, { 0x1d, 0x00 }, { 0x1e, 0x01 },
0166 { 0x23, 0x80 }, { 0x24, 0x00 }, { 0x25, 0x95 }, { 0x26, 0x05 },
0167 { 0x27, 0x2c }, { 0x32, 0x08 }, { 0x33, 0xa8 }, { 0x36, 0xaf },
0168 { 0x37, 0x7e }, { 0x55, 0xbf }, { 0x56, 0x3f }, { 0x57, 0xff },
0169 { 0x58, 0x9f }, { 0x76, 0xac }, { 0x77, 0xc0 }, { 0x78, 0x00 },
0170 { 0x79, 0x00 }, { 0x82, 0x6b }, { 0x83, 0x00 }, { 0x85, 0x11 },
0171 { 0x86, 0x3f },
0172 };
0173
0174 static const u16 ch_coeff_dab1[] = {
0175 0x001c, 0x0007, 0xffcd, 0x0056, 0xffa4, 0x0033, 0x0027, 0xff61,
0176 0x010e, 0xfec0, 0x0106, 0xffb8, 0xff1c, 0x023c, 0xfcb2, 0x039b,
0177 0xfd4e, 0x0055, 0x036a, 0xf7de, 0x0d21, 0xee72, 0x1499, 0x6a51,
0178 };
0179
0180 static const u16 ch_coeff_fmeu[] = {
0181 0x0000, 0xffff, 0x0001, 0x0002, 0xfffa, 0xffff, 0x0015, 0xffec,
0182 0xffde, 0x0054, 0xfff9, 0xff52, 0x00b8, 0x00a2, 0xfe0a, 0x00af,
0183 0x02e3, 0xfc14, 0xfe89, 0x089d, 0xfa2e, 0xf30f, 0x25be, 0x4eb6,
0184 };
0185
0186 static const u16 eq_coeff_fmeu1_ra02_m6db[] = {
0187 0x0040, 0xffc6, 0xfffa, 0x002c, 0x000d, 0xff90, 0x0037, 0x006e,
0188 0xffc0, 0xff5b, 0x006a, 0x00f0, 0xff57, 0xfe94, 0x0112, 0x0252,
0189 0xfe0c, 0xfc6a, 0x0385, 0x0553, 0xfa49, 0xf789, 0x0b91, 0x1a10,
0190 };
0191
0192 static const u16 ch_coeff_fmna[] = {
0193 0x0001, 0x0003, 0xfffe, 0xfff4, 0x0000, 0x001f, 0x000c, 0xffbc,
0194 0xffd3, 0x007d, 0x0075, 0xff33, 0xff01, 0x0131, 0x01ef, 0xfe60,
0195 0xfc7a, 0x020e, 0x0656, 0xfd94, 0xf395, 0x02ab, 0x2857, 0x3d3f,
0196 };
0197
0198 static const u16 eq_coeff_fmna1_ra02_m6db[] = {
0199 0xfff1, 0xffe1, 0xffef, 0x000e, 0x0030, 0x002f, 0xfff6, 0xffa7,
0200 0xff9d, 0x000a, 0x00a2, 0x00b5, 0xffea, 0xfed9, 0xfec5, 0x003d,
0201 0x0217, 0x021b, 0xff5a, 0xfc2b, 0xfcbd, 0x02c4, 0x0ac3, 0x0e85,
0202 };
0203
0204 static const u8 adc_presets[2][23] = {
0205 {
0206 0x83, 0x00, 0xcf, 0xb4, 0x0f, 0x2c, 0x0c, 0x49,
0207 0x00, 0x00, 0x00, 0x8c, 0x02, 0x02, 0x00, 0x04,
0208 0xec, 0x82, 0x4b, 0xcc, 0x01, 0x88, 0x0c,
0209 },
0210 {
0211 0x83, 0x00, 0xcf, 0xb4, 0x0f, 0x2c, 0x0c, 0x49,
0212 0x00, 0x00, 0x00, 0x8c, 0x02, 0x20, 0x33, 0x8c,
0213 0x57, 0xd7, 0x59, 0xb7, 0x65, 0x0e, 0x0c,
0214 },
0215 };
0216
0217
0218 static const struct v4l2_frequency_band eu_bands_rf = {
0219 .tuner = 0,
0220 .type = V4L2_TUNER_RF,
0221 .index = 0,
0222 .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
0223 .rangelow = 65000000,
0224 .rangehigh = 240000000,
0225 };
0226
0227 static const struct v4l2_frequency_band na_bands_rf = {
0228 .tuner = 0,
0229 .type = V4L2_TUNER_RF,
0230 .index = 0,
0231 .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
0232 .rangelow = 65000000,
0233 .rangehigh = 108000000,
0234 };
0235
0236
0237 static const struct regmap_range max2175_regmap_volatile_range[] = {
0238 regmap_reg_range(0x30, 0x35),
0239 regmap_reg_range(0x3a, 0x45),
0240 regmap_reg_range(0x59, 0x5e),
0241 regmap_reg_range(0x73, 0x75),
0242 };
0243
0244 static const struct regmap_access_table max2175_volatile_regs = {
0245 .yes_ranges = max2175_regmap_volatile_range,
0246 .n_yes_ranges = ARRAY_SIZE(max2175_regmap_volatile_range),
0247 };
0248
0249 static const struct reg_default max2175_reg_defaults[] = {
0250 { 0x00, 0x07},
0251 };
0252
0253 static const struct regmap_config max2175_regmap_config = {
0254 .reg_bits = 8,
0255 .val_bits = 8,
0256 .max_register = 0xff,
0257 .reg_defaults = max2175_reg_defaults,
0258 .num_reg_defaults = ARRAY_SIZE(max2175_reg_defaults),
0259 .volatile_table = &max2175_volatile_regs,
0260 .cache_type = REGCACHE_RBTREE,
0261 };
0262
0263 struct max2175 {
0264 struct v4l2_subdev sd;
0265 struct i2c_client *client;
0266
0267
0268 struct v4l2_ctrl_handler ctrl_hdl;
0269 struct v4l2_ctrl *lna_gain;
0270 struct v4l2_ctrl *if_gain;
0271 struct v4l2_ctrl *pll_lock;
0272 struct v4l2_ctrl *i2s_en;
0273 struct v4l2_ctrl *hsls;
0274 struct v4l2_ctrl *rx_mode;
0275
0276
0277 struct regmap *regmap;
0278
0279
0280 u32 freq;
0281 const struct max2175_rxmode *rx_modes;
0282 const struct v4l2_frequency_band *bands_rf;
0283
0284
0285 unsigned long xtal_freq;
0286 u32 decim_ratio;
0287 bool master;
0288 bool am_hiz;
0289
0290
0291 u8 rom_bbf_bw_am;
0292 u8 rom_bbf_bw_fm;
0293 u8 rom_bbf_bw_dab;
0294
0295
0296 bool mode_resolved;
0297 };
0298
0299 static inline struct max2175 *max2175_from_sd(struct v4l2_subdev *sd)
0300 {
0301 return container_of(sd, struct max2175, sd);
0302 }
0303
0304 static inline struct max2175 *max2175_from_ctrl_hdl(struct v4l2_ctrl_handler *h)
0305 {
0306 return container_of(h, struct max2175, ctrl_hdl);
0307 }
0308
0309
0310 static inline u8 max2175_get_bitval(u8 val, u8 msb, u8 lsb)
0311 {
0312 return (val & GENMASK(msb, lsb)) >> lsb;
0313 }
0314
0315
0316 static int max2175_read(struct max2175 *ctx, u8 idx, u8 *val)
0317 {
0318 u32 regval;
0319 int ret;
0320
0321 ret = regmap_read(ctx->regmap, idx, ®val);
0322 if (ret)
0323 mxm_err(ctx, "read ret(%d): idx 0x%02x\n", ret, idx);
0324 else
0325 *val = regval;
0326
0327 return ret;
0328 }
0329
0330 static int max2175_write(struct max2175 *ctx, u8 idx, u8 val)
0331 {
0332 int ret;
0333
0334 ret = regmap_write(ctx->regmap, idx, val);
0335 if (ret)
0336 mxm_err(ctx, "write ret(%d): idx 0x%02x val 0x%02x\n",
0337 ret, idx, val);
0338
0339 return ret;
0340 }
0341
0342 static u8 max2175_read_bits(struct max2175 *ctx, u8 idx, u8 msb, u8 lsb)
0343 {
0344 u8 val;
0345
0346 if (max2175_read(ctx, idx, &val))
0347 return 0;
0348
0349 return max2175_get_bitval(val, msb, lsb);
0350 }
0351
0352 static int max2175_write_bits(struct max2175 *ctx, u8 idx,
0353 u8 msb, u8 lsb, u8 newval)
0354 {
0355 int ret = regmap_update_bits(ctx->regmap, idx, GENMASK(msb, lsb),
0356 newval << lsb);
0357
0358 if (ret)
0359 mxm_err(ctx, "wbits ret(%d): idx 0x%02x\n", ret, idx);
0360
0361 return ret;
0362 }
0363
0364 static int max2175_write_bit(struct max2175 *ctx, u8 idx, u8 bit, u8 newval)
0365 {
0366 return max2175_write_bits(ctx, idx, bit, bit, newval);
0367 }
0368
0369
0370 static int max2175_poll_timeout(struct max2175 *ctx, u8 idx, u8 msb, u8 lsb,
0371 u8 exp_bitval, u32 timeout_us)
0372 {
0373 unsigned int val;
0374
0375 return regmap_read_poll_timeout(ctx->regmap, idx, val,
0376 (max2175_get_bitval(val, msb, lsb) == exp_bitval),
0377 1000, timeout_us);
0378 }
0379
0380 static int max2175_poll_csm_ready(struct max2175 *ctx)
0381 {
0382 int ret;
0383
0384 ret = max2175_poll_timeout(ctx, 69, 1, 1, 0, 50000);
0385 if (ret)
0386 mxm_err(ctx, "csm not ready\n");
0387
0388 return ret;
0389 }
0390
0391 #define MAX2175_IS_BAND_AM(ctx) \
0392 (max2175_read_bits(ctx, 5, 1, 0) == MAX2175_BAND_AM)
0393
0394 #define MAX2175_IS_BAND_VHF(ctx) \
0395 (max2175_read_bits(ctx, 5, 1, 0) == MAX2175_BAND_VHF)
0396
0397 #define MAX2175_IS_FM_MODE(ctx) \
0398 (max2175_read_bits(ctx, 12, 5, 4) == 0)
0399
0400 #define MAX2175_IS_FMHD_MODE(ctx) \
0401 (max2175_read_bits(ctx, 12, 5, 4) == 1)
0402
0403 #define MAX2175_IS_DAB_MODE(ctx) \
0404 (max2175_read_bits(ctx, 12, 5, 4) == 2)
0405
0406 static int max2175_band_from_freq(u32 freq)
0407 {
0408 if (freq >= 144000 && freq <= 26100000)
0409 return MAX2175_BAND_AM;
0410 else if (freq >= 65000000 && freq <= 108000000)
0411 return MAX2175_BAND_FM;
0412
0413 return MAX2175_BAND_VHF;
0414 }
0415
0416 static void max2175_i2s_enable(struct max2175 *ctx, bool enable)
0417 {
0418 if (enable)
0419
0420 max2175_write_bits(ctx, 104, 3, 0, 2);
0421 else
0422
0423 max2175_write_bits(ctx, 104, 3, 0, 9);
0424 mxm_dbg(ctx, "i2s %sabled\n", enable ? "en" : "dis");
0425 }
0426
0427 static void max2175_set_filter_coeffs(struct max2175 *ctx, u8 m_sel,
0428 u8 bank, const u16 *coeffs)
0429 {
0430 unsigned int i;
0431 u8 coeff_addr, upper_address = 24;
0432
0433 mxm_dbg(ctx, "set_filter_coeffs: m_sel %d bank %d\n", m_sel, bank);
0434 max2175_write_bits(ctx, 114, 5, 4, m_sel);
0435
0436 if (m_sel == 2)
0437 upper_address = 12;
0438
0439 for (i = 0; i < upper_address; i++) {
0440 coeff_addr = i + bank * 24;
0441 max2175_write(ctx, 115, coeffs[i] >> 8);
0442 max2175_write(ctx, 116, coeffs[i]);
0443 max2175_write(ctx, 117, coeff_addr | 1 << 7);
0444 }
0445 max2175_write_bit(ctx, 117, 7, 0);
0446 }
0447
0448 static void max2175_load_fmeu_1p2(struct max2175 *ctx)
0449 {
0450 unsigned int i;
0451
0452 for (i = 0; i < ARRAY_SIZE(fmeu1p2_map); i++)
0453 max2175_write(ctx, fmeu1p2_map[i].idx, fmeu1p2_map[i].val);
0454
0455 ctx->decim_ratio = 36;
0456
0457
0458 max2175_set_filter_coeffs(ctx, MAX2175_CH_MSEL, 0, ch_coeff_fmeu);
0459 max2175_set_filter_coeffs(ctx, MAX2175_EQ_MSEL, 0,
0460 eq_coeff_fmeu1_ra02_m6db);
0461 }
0462
0463 static void max2175_load_dab_1p2(struct max2175 *ctx)
0464 {
0465 unsigned int i;
0466
0467 for (i = 0; i < ARRAY_SIZE(dab12_map); i++)
0468 max2175_write(ctx, dab12_map[i].idx, dab12_map[i].val);
0469
0470 ctx->decim_ratio = 1;
0471
0472
0473 max2175_set_filter_coeffs(ctx, MAX2175_CH_MSEL, 2, ch_coeff_dab1);
0474 }
0475
0476 static void max2175_load_fmna_1p0(struct max2175 *ctx)
0477 {
0478 unsigned int i;
0479
0480 for (i = 0; i < ARRAY_SIZE(fmna1p0_map); i++)
0481 max2175_write(ctx, fmna1p0_map[i].idx, fmna1p0_map[i].val);
0482 }
0483
0484 static void max2175_load_fmna_2p0(struct max2175 *ctx)
0485 {
0486 unsigned int i;
0487
0488 for (i = 0; i < ARRAY_SIZE(fmna2p0_map); i++)
0489 max2175_write(ctx, fmna2p0_map[i].idx, fmna2p0_map[i].val);
0490 }
0491
0492 static void max2175_set_bbfilter(struct max2175 *ctx)
0493 {
0494 if (MAX2175_IS_BAND_AM(ctx)) {
0495 max2175_write_bits(ctx, 12, 3, 0, ctx->rom_bbf_bw_am);
0496 mxm_dbg(ctx, "set_bbfilter AM: rom %d\n", ctx->rom_bbf_bw_am);
0497 } else if (MAX2175_IS_DAB_MODE(ctx)) {
0498 max2175_write_bits(ctx, 12, 3, 0, ctx->rom_bbf_bw_dab);
0499 mxm_dbg(ctx, "set_bbfilter DAB: rom %d\n", ctx->rom_bbf_bw_dab);
0500 } else {
0501 max2175_write_bits(ctx, 12, 3, 0, ctx->rom_bbf_bw_fm);
0502 mxm_dbg(ctx, "set_bbfilter FM: rom %d\n", ctx->rom_bbf_bw_fm);
0503 }
0504 }
0505
0506 static int max2175_set_csm_mode(struct max2175 *ctx,
0507 enum max2175_csm_mode new_mode)
0508 {
0509 int ret = max2175_poll_csm_ready(ctx);
0510
0511 if (ret)
0512 return ret;
0513
0514 max2175_write_bits(ctx, 0, 2, 0, new_mode);
0515 mxm_dbg(ctx, "set csm new mode %d\n", new_mode);
0516
0517
0518 switch (new_mode) {
0519 case MAX2175_PRESET_TUNE:
0520 usleep_range(51100, 51500);
0521 break;
0522
0523
0524
0525
0526 default:
0527 break;
0528 }
0529
0530 return max2175_poll_csm_ready(ctx);
0531 }
0532
0533 static int max2175_csm_action(struct max2175 *ctx,
0534 enum max2175_csm_mode action)
0535 {
0536 int ret;
0537
0538 mxm_dbg(ctx, "csm_action: %d\n", action);
0539
0540
0541 ret = max2175_set_csm_mode(ctx, MAX2175_LOAD_TO_BUFFER);
0542 if (ret)
0543 return ret;
0544
0545 return max2175_set_csm_mode(ctx, MAX2175_PRESET_TUNE);
0546 }
0547
0548 static int max2175_set_lo_freq(struct max2175 *ctx, u32 lo_freq)
0549 {
0550 u8 lo_mult, loband_bits = 0, vcodiv_bits = 0;
0551 u32 int_desired, frac_desired;
0552 enum max2175_band band;
0553 int ret;
0554
0555 band = max2175_read_bits(ctx, 5, 1, 0);
0556 switch (band) {
0557 case MAX2175_BAND_AM:
0558 lo_mult = 16;
0559 break;
0560 case MAX2175_BAND_FM:
0561 if (lo_freq <= 74700000) {
0562 lo_mult = 16;
0563 } else if (lo_freq > 74700000 && lo_freq <= 110000000) {
0564 loband_bits = 1;
0565 lo_mult = 8;
0566 } else {
0567 loband_bits = 1;
0568 vcodiv_bits = 3;
0569 lo_mult = 8;
0570 }
0571 break;
0572 case MAX2175_BAND_VHF:
0573 if (lo_freq <= 210000000)
0574 vcodiv_bits = 2;
0575 else
0576 vcodiv_bits = 1;
0577
0578 loband_bits = 2;
0579 lo_mult = 4;
0580 break;
0581 default:
0582 loband_bits = 3;
0583 vcodiv_bits = 2;
0584 lo_mult = 2;
0585 break;
0586 }
0587
0588 if (band == MAX2175_BAND_L)
0589 lo_freq /= lo_mult;
0590 else
0591 lo_freq *= lo_mult;
0592
0593 int_desired = lo_freq / ctx->xtal_freq;
0594 frac_desired = div64_ul((u64)(lo_freq % ctx->xtal_freq) << 20,
0595 ctx->xtal_freq);
0596
0597
0598 ret = max2175_poll_csm_ready(ctx);
0599 if (ret)
0600 return ret;
0601
0602 mxm_dbg(ctx, "lo_mult %u int %u frac %u\n",
0603 lo_mult, int_desired, frac_desired);
0604
0605
0606 max2175_write(ctx, 1, int_desired);
0607 max2175_write_bits(ctx, 2, 3, 0, (frac_desired >> 16) & 0xf);
0608 max2175_write(ctx, 3, frac_desired >> 8);
0609 max2175_write(ctx, 4, frac_desired);
0610 max2175_write_bits(ctx, 5, 3, 2, loband_bits);
0611 max2175_write_bits(ctx, 6, 7, 6, vcodiv_bits);
0612
0613 return ret;
0614 }
0615
0616
0617
0618
0619
0620 static inline s64 max2175_round_closest(s64 dividend, s32 divisor)
0621 {
0622 if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0))
0623 return div_s64(dividend + divisor / 2, divisor);
0624
0625 return div_s64(dividend - divisor / 2, divisor);
0626 }
0627
0628 static int max2175_set_nco_freq(struct max2175 *ctx, s32 nco_freq)
0629 {
0630 s32 clock_rate = ctx->xtal_freq / ctx->decim_ratio;
0631 u32 nco_reg, abs_nco_freq = abs(nco_freq);
0632 s64 nco_val_desired;
0633 int ret;
0634
0635 if (abs_nco_freq < clock_rate / 2) {
0636 nco_val_desired = 2 * nco_freq;
0637 } else {
0638 nco_val_desired = 2LL * (clock_rate - abs_nco_freq);
0639 if (nco_freq < 0)
0640 nco_val_desired = -nco_val_desired;
0641 }
0642
0643 nco_reg = max2175_round_closest(nco_val_desired << 20, clock_rate);
0644
0645 if (nco_freq < 0)
0646 nco_reg += 0x200000;
0647
0648
0649 ret = max2175_poll_csm_ready(ctx);
0650 if (ret)
0651 return ret;
0652
0653 mxm_dbg(ctx, "freq %d desired %lld reg %u\n",
0654 nco_freq, nco_val_desired, nco_reg);
0655
0656
0657 max2175_write_bits(ctx, 7, 4, 0, (nco_reg >> 16) & 0x1f);
0658 max2175_write(ctx, 8, nco_reg >> 8);
0659 max2175_write(ctx, 9, nco_reg);
0660
0661 return ret;
0662 }
0663
0664 static int max2175_set_rf_freq_non_am_bands(struct max2175 *ctx, u64 freq,
0665 u32 lo_pos)
0666 {
0667 s64 adj_freq, low_if_freq;
0668 int ret;
0669
0670 mxm_dbg(ctx, "rf_freq: non AM bands\n");
0671
0672 if (MAX2175_IS_FM_MODE(ctx))
0673 low_if_freq = 128000;
0674 else if (MAX2175_IS_FMHD_MODE(ctx))
0675 low_if_freq = 228000;
0676 else
0677 return max2175_set_lo_freq(ctx, freq);
0678
0679 if (MAX2175_IS_BAND_VHF(ctx) == (lo_pos == MAX2175_LO_ABOVE_DESIRED))
0680 adj_freq = freq + low_if_freq;
0681 else
0682 adj_freq = freq - low_if_freq;
0683
0684 ret = max2175_set_lo_freq(ctx, adj_freq);
0685 if (ret)
0686 return ret;
0687
0688 return max2175_set_nco_freq(ctx, -low_if_freq);
0689 }
0690
0691 static int max2175_set_rf_freq(struct max2175 *ctx, u64 freq, u32 lo_pos)
0692 {
0693 int ret;
0694
0695 if (MAX2175_IS_BAND_AM(ctx))
0696 ret = max2175_set_nco_freq(ctx, freq);
0697 else
0698 ret = max2175_set_rf_freq_non_am_bands(ctx, freq, lo_pos);
0699
0700 mxm_dbg(ctx, "set_rf_freq: ret %d freq %llu\n", ret, freq);
0701
0702 return ret;
0703 }
0704
0705 static int max2175_tune_rf_freq(struct max2175 *ctx, u64 freq, u32 hsls)
0706 {
0707 int ret;
0708
0709 ret = max2175_set_rf_freq(ctx, freq, hsls);
0710 if (ret)
0711 return ret;
0712
0713 ret = max2175_csm_action(ctx, MAX2175_BUFFER_PLUS_PRESET_TUNE);
0714 if (ret)
0715 return ret;
0716
0717 mxm_dbg(ctx, "tune_rf_freq: old %u new %llu\n", ctx->freq, freq);
0718 ctx->freq = freq;
0719
0720 return ret;
0721 }
0722
0723 static void max2175_set_hsls(struct max2175 *ctx, u32 lo_pos)
0724 {
0725 mxm_dbg(ctx, "set_hsls: lo_pos %u\n", lo_pos);
0726
0727 if ((lo_pos == MAX2175_LO_BELOW_DESIRED) == MAX2175_IS_BAND_VHF(ctx))
0728 max2175_write_bit(ctx, 5, 4, 1);
0729 else
0730 max2175_write_bit(ctx, 5, 4, 0);
0731 }
0732
0733 static void max2175_set_eu_rx_mode(struct max2175 *ctx, u32 rx_mode)
0734 {
0735 switch (rx_mode) {
0736 case MAX2175_EU_FM_1_2:
0737 max2175_load_fmeu_1p2(ctx);
0738 break;
0739
0740 case MAX2175_DAB_1_2:
0741 max2175_load_dab_1p2(ctx);
0742 break;
0743 }
0744
0745 if (!ctx->master)
0746 max2175_write_bit(ctx, 30, 7, 1);
0747 }
0748
0749 static void max2175_set_na_rx_mode(struct max2175 *ctx, u32 rx_mode)
0750 {
0751 switch (rx_mode) {
0752 case MAX2175_NA_FM_1_0:
0753 max2175_load_fmna_1p0(ctx);
0754 break;
0755 case MAX2175_NA_FM_2_0:
0756 max2175_load_fmna_2p0(ctx);
0757 break;
0758 }
0759
0760 if (!ctx->master)
0761 max2175_write_bit(ctx, 30, 7, 1);
0762
0763 ctx->decim_ratio = 27;
0764
0765
0766 max2175_set_filter_coeffs(ctx, MAX2175_CH_MSEL, 0, ch_coeff_fmna);
0767 max2175_set_filter_coeffs(ctx, MAX2175_EQ_MSEL, 0,
0768 eq_coeff_fmna1_ra02_m6db);
0769 }
0770
0771 static int max2175_set_rx_mode(struct max2175 *ctx, u32 rx_mode)
0772 {
0773 mxm_dbg(ctx, "set_rx_mode: %u am_hiz %u\n", rx_mode, ctx->am_hiz);
0774 if (ctx->xtal_freq == MAX2175_EU_XTAL_FREQ)
0775 max2175_set_eu_rx_mode(ctx, rx_mode);
0776 else
0777 max2175_set_na_rx_mode(ctx, rx_mode);
0778
0779 if (ctx->am_hiz) {
0780 mxm_dbg(ctx, "setting AM HiZ related config\n");
0781 max2175_write_bit(ctx, 50, 5, 1);
0782 max2175_write_bit(ctx, 90, 7, 1);
0783 max2175_write_bits(ctx, 73, 1, 0, 2);
0784 max2175_write_bits(ctx, 80, 5, 0, 33);
0785 }
0786
0787
0788 max2175_set_bbfilter(ctx);
0789
0790
0791 max2175_set_hsls(ctx, ctx->hsls->cur.val);
0792
0793
0794 max2175_i2s_enable(ctx, ctx->i2s_en->cur.val);
0795
0796 ctx->mode_resolved = true;
0797
0798 return 0;
0799 }
0800
0801 static int max2175_rx_mode_from_freq(struct max2175 *ctx, u32 freq, u32 *mode)
0802 {
0803 unsigned int i;
0804 int band = max2175_band_from_freq(freq);
0805
0806
0807 for (i = 0; i <= ctx->rx_mode->maximum; i++) {
0808 if (ctx->rx_modes[i].band == band) {
0809 *mode = i;
0810 mxm_dbg(ctx, "rx_mode_from_freq: freq %u mode %d\n",
0811 freq, *mode);
0812 return 0;
0813 }
0814 }
0815
0816 return -EINVAL;
0817 }
0818
0819 static bool max2175_freq_rx_mode_valid(struct max2175 *ctx,
0820 u32 mode, u32 freq)
0821 {
0822 int band = max2175_band_from_freq(freq);
0823
0824 return (ctx->rx_modes[mode].band == band);
0825 }
0826
0827 static void max2175_load_adc_presets(struct max2175 *ctx)
0828 {
0829 unsigned int i, j;
0830
0831 for (i = 0; i < ARRAY_SIZE(adc_presets); i++)
0832 for (j = 0; j < ARRAY_SIZE(adc_presets[0]); j++)
0833 max2175_write(ctx, 146 + j + i * 55, adc_presets[i][j]);
0834 }
0835
0836 static int max2175_init_power_manager(struct max2175 *ctx)
0837 {
0838 int ret;
0839
0840
0841 max2175_write_bit(ctx, 99, 2, 0);
0842 usleep_range(1000, 1500);
0843 max2175_write_bit(ctx, 99, 2, 1);
0844
0845
0846 ret = max2175_poll_timeout(ctx, 69, 7, 7, 1, 50000);
0847 if (ret)
0848 mxm_err(ctx, "init pm failed\n");
0849
0850 return ret;
0851 }
0852
0853 static int max2175_recalibrate_adc(struct max2175 *ctx)
0854 {
0855 int ret;
0856
0857
0858 max2175_write(ctx, 150, 0xff);
0859 max2175_write(ctx, 205, 0xff);
0860 max2175_write(ctx, 147, 0x20);
0861 max2175_write(ctx, 147, 0x00);
0862 max2175_write(ctx, 202, 0x20);
0863 max2175_write(ctx, 202, 0x00);
0864
0865 ret = max2175_poll_timeout(ctx, 69, 4, 3, 3, 50000);
0866 if (ret)
0867 mxm_err(ctx, "adc recalibration failed\n");
0868
0869 return ret;
0870 }
0871
0872 static u8 max2175_read_rom(struct max2175 *ctx, u8 row)
0873 {
0874 u8 data = 0;
0875
0876 max2175_write_bit(ctx, 56, 4, 0);
0877 max2175_write_bits(ctx, 56, 3, 0, row);
0878
0879 usleep_range(2000, 2500);
0880 max2175_read(ctx, 58, &data);
0881
0882 max2175_write_bits(ctx, 56, 3, 0, 0);
0883
0884 mxm_dbg(ctx, "read_rom: row %d data 0x%02x\n", row, data);
0885
0886 return data;
0887 }
0888
0889 static void max2175_load_from_rom(struct max2175 *ctx)
0890 {
0891 u8 data = 0;
0892
0893 data = max2175_read_rom(ctx, 0);
0894 ctx->rom_bbf_bw_am = data & 0x0f;
0895 max2175_write_bits(ctx, 81, 3, 0, data >> 4);
0896
0897 data = max2175_read_rom(ctx, 1);
0898 ctx->rom_bbf_bw_fm = data & 0x0f;
0899 ctx->rom_bbf_bw_dab = data >> 4;
0900
0901 data = max2175_read_rom(ctx, 2);
0902 max2175_write_bits(ctx, 82, 4, 0, data & 0x1f);
0903 max2175_write_bits(ctx, 82, 7, 5, data >> 5);
0904
0905 data = max2175_read_rom(ctx, 3);
0906 if (ctx->am_hiz) {
0907 data &= 0x0f;
0908 data |= (max2175_read_rom(ctx, 7) & 0x40) >> 2;
0909 if (!data)
0910 data |= 2;
0911 } else {
0912 data = (data & 0xf0) >> 4;
0913 data |= (max2175_read_rom(ctx, 7) & 0x80) >> 3;
0914 if (!data)
0915 data |= 30;
0916 }
0917 max2175_write_bits(ctx, 80, 5, 0, data + 31);
0918
0919 data = max2175_read_rom(ctx, 6);
0920 max2175_write_bits(ctx, 81, 7, 6, data >> 6);
0921 }
0922
0923 static void max2175_load_full_fm_eu_1p0(struct max2175 *ctx)
0924 {
0925 unsigned int i;
0926
0927 for (i = 0; i < ARRAY_SIZE(full_fm_eu_1p0); i++)
0928 max2175_write(ctx, i + 1, full_fm_eu_1p0[i]);
0929
0930 usleep_range(5000, 5500);
0931 ctx->decim_ratio = 36;
0932 }
0933
0934 static void max2175_load_full_fm_na_1p0(struct max2175 *ctx)
0935 {
0936 unsigned int i;
0937
0938 for (i = 0; i < ARRAY_SIZE(full_fm_na_1p0); i++)
0939 max2175_write(ctx, i + 1, full_fm_na_1p0[i]);
0940
0941 usleep_range(5000, 5500);
0942 ctx->decim_ratio = 27;
0943 }
0944
0945 static int max2175_core_init(struct max2175 *ctx, u32 refout_bits)
0946 {
0947 int ret;
0948
0949
0950 if (ctx->xtal_freq == MAX2175_EU_XTAL_FREQ)
0951 max2175_load_full_fm_eu_1p0(ctx);
0952 else
0953 max2175_load_full_fm_na_1p0(ctx);
0954
0955
0956 if (!ctx->master)
0957 max2175_write_bit(ctx, 30, 7, 1);
0958
0959 mxm_dbg(ctx, "refout_bits %u\n", refout_bits);
0960
0961
0962 max2175_write_bits(ctx, 56, 7, 5, refout_bits);
0963
0964
0965 max2175_write_bit(ctx, 99, 1, 0);
0966 usleep_range(1000, 1500);
0967 max2175_write_bit(ctx, 99, 1, 1);
0968
0969
0970 max2175_load_adc_presets(ctx);
0971
0972
0973 ret = max2175_init_power_manager(ctx);
0974 if (ret)
0975 return ret;
0976
0977
0978 ret = max2175_recalibrate_adc(ctx);
0979 if (ret)
0980 return ret;
0981
0982
0983 max2175_load_from_rom(ctx);
0984
0985 if (ctx->xtal_freq == MAX2175_EU_XTAL_FREQ) {
0986
0987 max2175_set_filter_coeffs(ctx, MAX2175_CH_MSEL, 0,
0988 ch_coeff_fmeu);
0989 max2175_set_filter_coeffs(ctx, MAX2175_EQ_MSEL, 0,
0990 eq_coeff_fmeu1_ra02_m6db);
0991 } else {
0992
0993 max2175_set_filter_coeffs(ctx, MAX2175_CH_MSEL, 0,
0994 ch_coeff_fmna);
0995 max2175_set_filter_coeffs(ctx, MAX2175_EQ_MSEL, 0,
0996 eq_coeff_fmna1_ra02_m6db);
0997 }
0998 mxm_dbg(ctx, "core initialized\n");
0999
1000 return 0;
1001 }
1002
1003 static void max2175_s_ctrl_rx_mode(struct max2175 *ctx, u32 rx_mode)
1004 {
1005
1006 max2175_set_rx_mode(ctx, rx_mode);
1007
1008 mxm_dbg(ctx, "s_ctrl_rx_mode: %u curr freq %u\n", rx_mode, ctx->freq);
1009
1010
1011 if (max2175_freq_rx_mode_valid(ctx, rx_mode, ctx->freq))
1012 max2175_tune_rf_freq(ctx, ctx->freq, ctx->hsls->cur.val);
1013 else
1014
1015 max2175_tune_rf_freq(ctx, ctx->rx_modes[rx_mode].freq,
1016 ctx->hsls->cur.val);
1017 }
1018
1019 static int max2175_s_ctrl(struct v4l2_ctrl *ctrl)
1020 {
1021 struct max2175 *ctx = max2175_from_ctrl_hdl(ctrl->handler);
1022
1023 mxm_dbg(ctx, "s_ctrl: id 0x%x, val %u\n", ctrl->id, ctrl->val);
1024 switch (ctrl->id) {
1025 case V4L2_CID_MAX2175_I2S_ENABLE:
1026 max2175_i2s_enable(ctx, ctrl->val);
1027 break;
1028 case V4L2_CID_MAX2175_HSLS:
1029 max2175_set_hsls(ctx, ctrl->val);
1030 break;
1031 case V4L2_CID_MAX2175_RX_MODE:
1032 max2175_s_ctrl_rx_mode(ctx, ctrl->val);
1033 break;
1034 }
1035
1036 return 0;
1037 }
1038
1039 static u32 max2175_get_lna_gain(struct max2175 *ctx)
1040 {
1041 enum max2175_band band = max2175_read_bits(ctx, 5, 1, 0);
1042
1043 switch (band) {
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);
1050 default:
1051 return 0;
1052 }
1053 }
1054
1055 static int max2175_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1056 {
1057 struct max2175 *ctx = max2175_from_ctrl_hdl(ctrl->handler);
1058
1059 switch (ctrl->id) {
1060 case V4L2_CID_RF_TUNER_LNA_GAIN:
1061 ctrl->val = max2175_get_lna_gain(ctx);
1062 break;
1063 case V4L2_CID_RF_TUNER_IF_GAIN:
1064 ctrl->val = max2175_read_bits(ctx, 49, 4, 0);
1065 break;
1066 case V4L2_CID_RF_TUNER_PLL_LOCK:
1067 ctrl->val = (max2175_read_bits(ctx, 60, 7, 6) == 3);
1068 break;
1069 }
1070
1071 return 0;
1072 };
1073
1074 static int max2175_set_freq_and_mode(struct max2175 *ctx, u32 freq)
1075 {
1076 u32 rx_mode;
1077 int ret;
1078
1079
1080 ret = max2175_rx_mode_from_freq(ctx, freq, &rx_mode);
1081 if (ret)
1082 return ret;
1083
1084 mxm_dbg(ctx, "set_freq_and_mode: freq %u rx_mode %d\n", freq, rx_mode);
1085
1086
1087 max2175_set_rx_mode(ctx, rx_mode);
1088 ctx->rx_mode->cur.val = rx_mode;
1089
1090
1091 return max2175_tune_rf_freq(ctx, freq, ctx->hsls->cur.val);
1092 }
1093
1094 static int max2175_s_frequency(struct v4l2_subdev *sd,
1095 const struct v4l2_frequency *vf)
1096 {
1097 struct max2175 *ctx = max2175_from_sd(sd);
1098 u32 freq;
1099 int ret = 0;
1100
1101 mxm_dbg(ctx, "s_freq: new %u curr %u, mode_resolved %d\n",
1102 vf->frequency, ctx->freq, ctx->mode_resolved);
1103
1104 if (vf->tuner != 0)
1105 return -EINVAL;
1106
1107 freq = clamp(vf->frequency, ctx->bands_rf->rangelow,
1108 ctx->bands_rf->rangehigh);
1109
1110
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);
1114 else
1115
1116 ret = max2175_set_freq_and_mode(ctx, freq);
1117
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);
1120
1121 return ret;
1122 }
1123
1124 static int max2175_g_frequency(struct v4l2_subdev *sd,
1125 struct v4l2_frequency *vf)
1126 {
1127 struct max2175 *ctx = max2175_from_sd(sd);
1128
1129 if (vf->tuner != 0)
1130 return -EINVAL;
1131
1132
1133 vf->type = V4L2_TUNER_RF;
1134 vf->frequency = ctx->freq;
1135
1136 return 0;
1137 }
1138
1139 static int max2175_enum_freq_bands(struct v4l2_subdev *sd,
1140 struct v4l2_frequency_band *band)
1141 {
1142 struct max2175 *ctx = max2175_from_sd(sd);
1143
1144 if (band->tuner != 0 || band->index != 0)
1145 return -EINVAL;
1146
1147 *band = *ctx->bands_rf;
1148
1149 return 0;
1150 }
1151
1152 static int max2175_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
1153 {
1154 struct max2175 *ctx = max2175_from_sd(sd);
1155
1156 if (vt->index > 0)
1157 return -EINVAL;
1158
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;
1164
1165 return 0;
1166 }
1167
1168 static int max2175_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
1169 {
1170
1171 if (vt->index > 0)
1172 return -EINVAL;
1173
1174 return 0;
1175 }
1176
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,
1183 };
1184
1185 static const struct v4l2_subdev_ops max2175_ops = {
1186 .tuner = &max2175_tuner_ops,
1187 };
1188
1189 static const struct v4l2_ctrl_ops max2175_ctrl_ops = {
1190 .s_ctrl = max2175_s_ctrl,
1191 .g_volatile_ctrl = max2175_g_volatile_ctrl,
1192 };
1193
1194
1195
1196
1197
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,
1203 .min = 0,
1204 .max = 1,
1205 .step = 1,
1206 .def = 1,
1207 .is_private = 1,
1208 };
1209
1210
1211
1212
1213
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,
1219 .min = 0,
1220 .max = 1,
1221 .step = 1,
1222 .def = 1,
1223 };
1224
1225
1226
1227
1228
1229
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",
1233 };
1234
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",
1238 };
1239
1240 static const struct v4l2_ctrl_config max2175_eu_rx_mode = {
1241 .ops = &max2175_ctrl_ops,
1242 .id = V4L2_CID_MAX2175_RX_MODE,
1243 .name = "RX Mode",
1244 .type = V4L2_CTRL_TYPE_MENU,
1245 .max = ARRAY_SIZE(max2175_ctrl_eu_rx_modes) - 1,
1246 .def = 0,
1247 .qmenu = max2175_ctrl_eu_rx_modes,
1248 };
1249
1250 static const struct v4l2_ctrl_config max2175_na_rx_mode = {
1251 .ops = &max2175_ctrl_ops,
1252 .id = V4L2_CID_MAX2175_RX_MODE,
1253 .name = "RX Mode",
1254 .type = V4L2_CTRL_TYPE_MENU,
1255 .max = ARRAY_SIZE(max2175_ctrl_na_rx_modes) - 1,
1256 .def = 0,
1257 .qmenu = max2175_ctrl_na_rx_modes,
1258 };
1259
1260 static int max2175_refout_load_to_bits(struct i2c_client *client, u32 load,
1261 u32 *bits)
1262 {
1263 if (load <= 40)
1264 *bits = load / 10;
1265 else if (load >= 60 && load <= 70)
1266 *bits = load / 10 - 1;
1267 else
1268 return -EINVAL;
1269
1270 return 0;
1271 }
1272
1273 static int max2175_probe(struct i2c_client *client)
1274 {
1275 bool master = true, am_hiz = false;
1276 u32 refout_load, refout_bits = 0;
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;
1283 struct clk *clk;
1284 int ret;
1285
1286
1287 np = of_parse_phandle(client->dev.of_node, "maxim,master", 0);
1288 if (np) {
1289 master = false;
1290 of_node_put(np);
1291 }
1292
1293 fwnode = of_fwnode_handle(client->dev.of_node);
1294 if (fwnode_property_present(fwnode, "maxim,am-hiz-filter"))
1295 am_hiz = true;
1296
1297 if (!fwnode_property_read_u32(fwnode, "maxim,refout-load",
1298 &refout_load)) {
1299 ret = max2175_refout_load_to_bits(client, refout_load,
1300 &refout_bits);
1301 if (ret) {
1302 dev_err(&client->dev, "invalid refout_load %u\n",
1303 refout_load);
1304 return -EINVAL;
1305 }
1306 }
1307
1308 clk = devm_clk_get(&client->dev, NULL);
1309 if (IS_ERR(clk)) {
1310 ret = PTR_ERR(clk);
1311 dev_err(&client->dev, "cannot get clock %d\n", ret);
1312 return ret;
1313 }
1314
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);
1319 return -ENODEV;
1320 }
1321
1322
1323 ctx = devm_kzalloc(&client->dev, sizeof(*ctx), GFP_KERNEL);
1324 if (ctx == NULL)
1325 return -ENOMEM;
1326
1327 sd = &ctx->sd;
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);
1334
1335 v4l2_i2c_subdev_init(sd, client, &max2175_ops);
1336 ctx->client = client;
1337
1338 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1339
1340
1341 hdl = &ctx->ctrl_hdl;
1342 ret = v4l2_ctrl_handler_init(hdl, 7);
1343 if (ret)
1344 return ret;
1345
1346 ctx->lna_gain = v4l2_ctrl_new_std(hdl, &max2175_ctrl_ops,
1347 V4L2_CID_RF_TUNER_LNA_GAIN,
1348 0, 63, 1, 0);
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,
1353 0, 31, 1, 0);
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,
1358 0, 1, 1, 0);
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);
1363
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;
1369 } else {
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;
1374 }
1375 ctx->sd.ctrl_handler = &ctx->ctrl_hdl;
1376
1377
1378 ctx->freq = ctx->bands_rf->rangelow;
1379
1380
1381 ret = v4l2_async_register_subdev(sd);
1382 if (ret) {
1383 dev_err(&client->dev, "register subdev failed\n");
1384 goto err_reg;
1385 }
1386
1387
1388 ret = max2175_core_init(ctx, refout_bits);
1389 if (ret)
1390 goto err_init;
1391
1392 ret = v4l2_ctrl_handler_setup(hdl);
1393 if (ret)
1394 goto err_init;
1395
1396 return 0;
1397
1398 err_init:
1399 v4l2_async_unregister_subdev(sd);
1400 err_reg:
1401 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1402
1403 return ret;
1404 }
1405
1406 static int max2175_remove(struct i2c_client *client)
1407 {
1408 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1409 struct max2175 *ctx = max2175_from_sd(sd);
1410
1411 v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
1412 v4l2_async_unregister_subdev(sd);
1413
1414 return 0;
1415 }
1416
1417 static const struct i2c_device_id max2175_id[] = {
1418 { DRIVER_NAME, 0},
1419 {},
1420 };
1421 MODULE_DEVICE_TABLE(i2c, max2175_id);
1422
1423 static const struct of_device_id max2175_of_ids[] = {
1424 { .compatible = "maxim,max2175", },
1425 { }
1426 };
1427 MODULE_DEVICE_TABLE(of, max2175_of_ids);
1428
1429 static struct i2c_driver max2175_driver = {
1430 .driver = {
1431 .name = DRIVER_NAME,
1432 .of_match_table = max2175_of_ids,
1433 },
1434 .probe_new = max2175_probe,
1435 .remove = max2175_remove,
1436 .id_table = max2175_id,
1437 };
1438
1439 module_i2c_driver(max2175_driver);
1440
1441 MODULE_DESCRIPTION("Maxim MAX2175 RF to Bits tuner driver");
1442 MODULE_LICENSE("GPL v2");
1443 MODULE_AUTHOR("Ramesh Shanmugasundaram <ramesh.shanmugasundaram@bp.renesas.com>");