456 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * ITE IT913X silicon tuner driver4 *5 * Copyright (C) 2011 Malcolm Priestley (tvboxspy@gmail.com)6 * IT9137 Copyright (C) ITE Tech Inc.7 */8 9#include "it913x.h"10#include <linux/platform_device.h>11#include <linux/regmap.h>12 13struct it913x_dev {14 struct platform_device *pdev;15 struct regmap *regmap;16 struct dvb_frontend *fe;17 u8 chip_ver:2;18 u8 role:2;19 u16 xtal;20 u8 fdiv;21 u8 clk_mode;22 u32 fn_min;23 bool active;24};25 26static int it913x_init(struct dvb_frontend *fe)27{28 struct it913x_dev *dev = fe->tuner_priv;29 struct platform_device *pdev = dev->pdev;30 int ret;31 unsigned int utmp;32 u8 iqik_m_cal, nv_val, buf[2];33 static const u8 nv[] = {48, 32, 24, 16, 12, 8, 6, 4, 2};34 unsigned long timeout;35 36 dev_dbg(&pdev->dev, "role %u\n", dev->role);37 38 ret = regmap_write(dev->regmap, 0x80ec4c, 0x68);39 if (ret)40 goto err;41 42 usleep_range(10000, 100000);43 44 ret = regmap_read(dev->regmap, 0x80ec86, &utmp);45 if (ret)46 goto err;47 48 switch (utmp) {49 case 0:50 /* 12.000 MHz */51 dev->clk_mode = utmp;52 dev->xtal = 2000;53 dev->fdiv = 3;54 iqik_m_cal = 16;55 break;56 case 1:57 /* 20.480 MHz */58 dev->clk_mode = utmp;59 dev->xtal = 640;60 dev->fdiv = 1;61 iqik_m_cal = 6;62 break;63 default:64 dev_err(&pdev->dev, "unknown clock identifier %d\n", utmp);65 ret = -EINVAL;66 goto err;67 }68 69 ret = regmap_read(dev->regmap, 0x80ed03, &utmp);70 if (ret)71 goto err;72 73 else if (utmp < ARRAY_SIZE(nv))74 nv_val = nv[utmp];75 else76 nv_val = 2;77 78 #define TIMEOUT 5079 timeout = jiffies + msecs_to_jiffies(TIMEOUT);80 while (!time_after(jiffies, timeout)) {81 ret = regmap_bulk_read(dev->regmap, 0x80ed23, buf, 2);82 if (ret)83 goto err;84 85 utmp = (buf[1] << 8) | (buf[0] << 0);86 if (utmp)87 break;88 }89 90 dev_dbg(&pdev->dev, "r_fbc_m_bdry took %u ms, val %u\n",91 jiffies_to_msecs(jiffies) -92 (jiffies_to_msecs(timeout) - TIMEOUT), utmp);93 94 dev->fn_min = dev->xtal * utmp;95 dev->fn_min /= (dev->fdiv * nv_val);96 dev->fn_min *= 1000;97 dev_dbg(&pdev->dev, "fn_min %u\n", dev->fn_min);98 99 /*100 * Chip version BX never sets that flag so we just wait 50ms in that101 * case. It is possible poll BX similarly than AX and then timeout in102 * order to get 50ms delay, but that causes about 120 extra I2C103 * messages. As for now, we just wait and reduce IO.104 */105 if (dev->chip_ver == 1) {106 #define TIMEOUT 50107 timeout = jiffies + msecs_to_jiffies(TIMEOUT);108 while (!time_after(jiffies, timeout)) {109 ret = regmap_read(dev->regmap, 0x80ec82, &utmp);110 if (ret)111 goto err;112 113 if (utmp)114 break;115 }116 117 dev_dbg(&pdev->dev, "p_tsm_init_mode took %u ms, val %u\n",118 jiffies_to_msecs(jiffies) -119 (jiffies_to_msecs(timeout) - TIMEOUT), utmp);120 } else {121 msleep(50);122 }123 124 ret = regmap_write(dev->regmap, 0x80ed81, iqik_m_cal);125 if (ret)126 goto err;127 128 ret = regmap_write(dev->regmap, 0x80ec57, 0x00);129 if (ret)130 goto err;131 132 ret = regmap_write(dev->regmap, 0x80ec58, 0x00);133 if (ret)134 goto err;135 136 ret = regmap_write(dev->regmap, 0x80ec40, 0x01);137 if (ret)138 goto err;139 140 dev->active = true;141 142 return 0;143err:144 dev_dbg(&pdev->dev, "failed %d\n", ret);145 return ret;146}147 148static int it913x_sleep(struct dvb_frontend *fe)149{150 struct it913x_dev *dev = fe->tuner_priv;151 struct platform_device *pdev = dev->pdev;152 int ret, len;153 154 dev_dbg(&pdev->dev, "role %u\n", dev->role);155 156 dev->active = false;157 158 ret = regmap_bulk_write(dev->regmap, 0x80ec40, "\x00", 1);159 if (ret)160 goto err;161 162 /*163 * Writing '0x00' to master tuner register '0x80ec08' causes slave tuner164 * communication lost. Due to that, we cannot put master full sleep.165 */166 if (dev->role == IT913X_ROLE_DUAL_MASTER)167 len = 4;168 else169 len = 15;170 171 dev_dbg(&pdev->dev, "role %u, len %d\n", dev->role, len);172 173 ret = regmap_bulk_write(dev->regmap, 0x80ec02,174 "\x3f\x1f\x3f\x3e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",175 len);176 if (ret)177 goto err;178 179 ret = regmap_bulk_write(dev->regmap, 0x80ec12, "\x00\x00\x00\x00", 4);180 if (ret)181 goto err;182 183 ret = regmap_bulk_write(dev->regmap, 0x80ec17,184 "\x00\x00\x00\x00\x00\x00\x00\x00\x00", 9);185 if (ret)186 goto err;187 188 ret = regmap_bulk_write(dev->regmap, 0x80ec22,189 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10);190 if (ret)191 goto err;192 193 ret = regmap_bulk_write(dev->regmap, 0x80ec20, "\x00", 1);194 if (ret)195 goto err;196 197 ret = regmap_bulk_write(dev->regmap, 0x80ec3f, "\x01", 1);198 if (ret)199 goto err;200 201 return 0;202err:203 dev_dbg(&pdev->dev, "failed %d\n", ret);204 return ret;205}206 207static int it913x_set_params(struct dvb_frontend *fe)208{209 struct it913x_dev *dev = fe->tuner_priv;210 struct platform_device *pdev = dev->pdev;211 struct dtv_frontend_properties *c = &fe->dtv_property_cache;212 int ret;213 unsigned int utmp;214 u32 pre_lo_freq, t_cal_freq;215 u16 iqik_m_cal, n_div;216 u8 u8tmp, n, l_band, lna_band;217 218 dev_dbg(&pdev->dev, "role=%u, frequency %u, bandwidth_hz %u\n",219 dev->role, c->frequency, c->bandwidth_hz);220 221 if (!dev->active) {222 ret = -EINVAL;223 goto err;224 }225 226 if (c->frequency <= 74000000) {227 n_div = 48;228 n = 0;229 } else if (c->frequency <= 111000000) {230 n_div = 32;231 n = 1;232 } else if (c->frequency <= 148000000) {233 n_div = 24;234 n = 2;235 } else if (c->frequency <= 222000000) {236 n_div = 16;237 n = 3;238 } else if (c->frequency <= 296000000) {239 n_div = 12;240 n = 4;241 } else if (c->frequency <= 445000000) {242 n_div = 8;243 n = 5;244 } else if (c->frequency <= dev->fn_min) {245 n_div = 6;246 n = 6;247 } else if (c->frequency <= 950000000) {248 n_div = 4;249 n = 7;250 } else {251 n_div = 2;252 n = 0;253 }254 255 ret = regmap_read(dev->regmap, 0x80ed81, &utmp);256 if (ret)257 goto err;258 259 iqik_m_cal = utmp * n_div;260 261 if (utmp < 0x20) {262 if (dev->clk_mode == 0)263 iqik_m_cal = (iqik_m_cal * 9) >> 5;264 else265 iqik_m_cal >>= 1;266 } else {267 iqik_m_cal = 0x40 - iqik_m_cal;268 if (dev->clk_mode == 0)269 iqik_m_cal = ~((iqik_m_cal * 9) >> 5);270 else271 iqik_m_cal = ~(iqik_m_cal >> 1);272 }273 274 t_cal_freq = (c->frequency / 1000) * n_div * dev->fdiv;275 pre_lo_freq = t_cal_freq / dev->xtal;276 utmp = pre_lo_freq * dev->xtal;277 278 if ((t_cal_freq - utmp) >= (dev->xtal >> 1))279 pre_lo_freq++;280 281 pre_lo_freq += (u32) n << 13;282 /* Frequency OMEGA_IQIK_M_CAL_MID*/283 t_cal_freq = pre_lo_freq + (u32)iqik_m_cal;284 dev_dbg(&pdev->dev, "t_cal_freq %u, pre_lo_freq %u\n",285 t_cal_freq, pre_lo_freq);286 287 if (c->frequency <= 440000000) {288 l_band = 0;289 lna_band = 0;290 } else if (c->frequency <= 484000000) {291 l_band = 1;292 lna_band = 1;293 } else if (c->frequency <= 533000000) {294 l_band = 1;295 lna_band = 2;296 } else if (c->frequency <= 587000000) {297 l_band = 1;298 lna_band = 3;299 } else if (c->frequency <= 645000000) {300 l_band = 1;301 lna_band = 4;302 } else if (c->frequency <= 710000000) {303 l_band = 1;304 lna_band = 5;305 } else if (c->frequency <= 782000000) {306 l_band = 1;307 lna_band = 6;308 } else if (c->frequency <= 860000000) {309 l_band = 1;310 lna_band = 7;311 } else if (c->frequency <= 1492000000) {312 l_band = 1;313 lna_band = 0;314 } else if (c->frequency <= 1685000000) {315 l_band = 1;316 lna_band = 1;317 } else {318 ret = -EINVAL;319 goto err;320 }321 322 /* XXX: latest windows driver does not set that at all */323 ret = regmap_write(dev->regmap, 0x80ee06, lna_band);324 if (ret)325 goto err;326 327 if (c->bandwidth_hz <= 5000000)328 u8tmp = 0;329 else if (c->bandwidth_hz <= 6000000)330 u8tmp = 2;331 else if (c->bandwidth_hz <= 7000000)332 u8tmp = 4;333 else334 u8tmp = 6; /* 8000000 */335 336 ret = regmap_write(dev->regmap, 0x80ec56, u8tmp);337 if (ret)338 goto err;339 340 /* XXX: latest windows driver sets different value (a8 != 68) */341 ret = regmap_write(dev->regmap, 0x80ec4c, 0xa0 | (l_band << 3));342 if (ret)343 goto err;344 345 ret = regmap_write(dev->regmap, 0x80ec4d, (t_cal_freq >> 0) & 0xff);346 if (ret)347 goto err;348 349 ret = regmap_write(dev->regmap, 0x80ec4e, (t_cal_freq >> 8) & 0xff);350 if (ret)351 goto err;352 353 ret = regmap_write(dev->regmap, 0x80011e, (pre_lo_freq >> 0) & 0xff);354 if (ret)355 goto err;356 357 ret = regmap_write(dev->regmap, 0x80011f, (pre_lo_freq >> 8) & 0xff);358 if (ret)359 goto err;360 361 return 0;362err:363 dev_dbg(&pdev->dev, "failed %d\n", ret);364 return ret;365}366 367static const struct dvb_tuner_ops it913x_tuner_ops = {368 .info = {369 .name = "ITE IT913X",370 .frequency_min_hz = 174 * MHz,371 .frequency_max_hz = 862 * MHz,372 },373 374 .init = it913x_init,375 .sleep = it913x_sleep,376 .set_params = it913x_set_params,377};378 379static int it913x_probe(struct platform_device *pdev)380{381 struct it913x_platform_data *pdata = pdev->dev.platform_data;382 struct dvb_frontend *fe = pdata->fe;383 struct it913x_dev *dev;384 const struct platform_device_id *id = platform_get_device_id(pdev);385 int ret;386 char *chip_ver_str;387 388 dev = kzalloc(sizeof(struct it913x_dev), GFP_KERNEL);389 if (dev == NULL) {390 ret = -ENOMEM;391 dev_err(&pdev->dev, "kzalloc() failed\n");392 goto err;393 }394 395 dev->pdev = pdev;396 dev->regmap = pdata->regmap;397 dev->fe = pdata->fe;398 dev->chip_ver = id->driver_data;399 dev->role = pdata->role;400 401 fe->tuner_priv = dev;402 memcpy(&fe->ops.tuner_ops, &it913x_tuner_ops,403 sizeof(struct dvb_tuner_ops));404 platform_set_drvdata(pdev, dev);405 406 if (dev->chip_ver == 1)407 chip_ver_str = "AX";408 else if (dev->chip_ver == 2)409 chip_ver_str = "BX";410 else411 chip_ver_str = "??";412 413 dev_info(&pdev->dev, "ITE IT913X %s successfully attached\n",414 chip_ver_str);415 dev_dbg(&pdev->dev, "chip_ver %u, role %u\n", dev->chip_ver, dev->role);416 return 0;417err:418 dev_dbg(&pdev->dev, "failed %d\n", ret);419 return ret;420}421 422static void it913x_remove(struct platform_device *pdev)423{424 struct it913x_dev *dev = platform_get_drvdata(pdev);425 struct dvb_frontend *fe = dev->fe;426 427 dev_dbg(&pdev->dev, "\n");428 429 memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));430 fe->tuner_priv = NULL;431 kfree(dev);432}433 434static const struct platform_device_id it913x_id_table[] = {435 {"it9133ax-tuner", 1},436 {"it9133bx-tuner", 2},437 {},438};439MODULE_DEVICE_TABLE(platform, it913x_id_table);440 441static struct platform_driver it913x_driver = {442 .driver = {443 .name = "it913x",444 .suppress_bind_attrs = true,445 },446 .probe = it913x_probe,447 .remove_new = it913x_remove,448 .id_table = it913x_id_table,449};450 451module_platform_driver(it913x_driver);452 453MODULE_DESCRIPTION("ITE IT913X silicon tuner driver");454MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");455MODULE_LICENSE("GPL");456