root/drivers/media/dvb-frontends/zd1301_demod.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. zd1301_demod_wreg
  2. zd1301_demod_rreg
  3. zd1301_demod_set_frontend
  4. zd1301_demod_sleep
  5. zd1301_demod_init
  6. zd1301_demod_get_tune_settings
  7. zd1301_demod_read_status
  8. zd1301_demod_get_dvb_frontend
  9. zd1301_demod_i2c_master_xfer
  10. zd1301_demod_i2c_functionality
  11. zd1301_demod_get_i2c_adapter
  12. zd1301_demod_probe
  13. zd1301_demod_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * ZyDAS ZD1301 driver (demodulator)
   4  *
   5  * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
   6  */
   7 
   8 #include "zd1301_demod.h"
   9 
  10 static u8 zd1301_demod_gain = 0x38;
  11 module_param_named(gain, zd1301_demod_gain, byte, 0644);
  12 MODULE_PARM_DESC(gain, "gain (value: 0x00 - 0x70, default: 0x38)");
  13 
  14 struct zd1301_demod_dev {
  15         struct platform_device *pdev;
  16         struct dvb_frontend frontend;
  17         struct i2c_adapter adapter;
  18         u8 gain;
  19 };
  20 
  21 static int zd1301_demod_wreg(struct zd1301_demod_dev *dev, u16 reg, u8 val)
  22 {
  23         struct platform_device *pdev = dev->pdev;
  24         struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
  25 
  26         return pdata->reg_write(pdata->reg_priv, reg, val);
  27 }
  28 
  29 static int zd1301_demod_rreg(struct zd1301_demod_dev *dev, u16 reg, u8 *val)
  30 {
  31         struct platform_device *pdev = dev->pdev;
  32         struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
  33 
  34         return pdata->reg_read(pdata->reg_priv, reg, val);
  35 }
  36 
  37 static int zd1301_demod_set_frontend(struct dvb_frontend *fe)
  38 {
  39         struct zd1301_demod_dev *dev = fe->demodulator_priv;
  40         struct platform_device *pdev = dev->pdev;
  41         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  42         int ret;
  43         u32 if_frequency;
  44         u8 r6a50_val;
  45 
  46         dev_dbg(&pdev->dev, "frequency=%u bandwidth_hz=%u\n",
  47                 c->frequency, c->bandwidth_hz);
  48 
  49         /* Program tuner */
  50         if (fe->ops.tuner_ops.set_params &&
  51             fe->ops.tuner_ops.get_if_frequency) {
  52                 ret = fe->ops.tuner_ops.set_params(fe);
  53                 if (ret)
  54                         goto err;
  55                 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
  56                 if (ret)
  57                         goto err;
  58         } else {
  59                 ret = -EINVAL;
  60                 goto err;
  61         }
  62 
  63         dev_dbg(&pdev->dev, "if_frequency=%u\n", if_frequency);
  64         if (if_frequency != 36150000) {
  65                 ret = -EINVAL;
  66                 goto err;
  67         }
  68 
  69         switch (c->bandwidth_hz) {
  70         case 6000000:
  71                 r6a50_val = 0x78;
  72                 break;
  73         case 7000000:
  74                 r6a50_val = 0x68;
  75                 break;
  76         case 8000000:
  77                 r6a50_val = 0x58;
  78                 break;
  79         default:
  80                 ret = -EINVAL;
  81                 goto err;
  82         }
  83 
  84         ret = zd1301_demod_wreg(dev, 0x6a60, 0x11);
  85         if (ret)
  86                 goto err;
  87         ret = zd1301_demod_wreg(dev, 0x6a47, 0x46);
  88         if (ret)
  89                 goto err;
  90         ret = zd1301_demod_wreg(dev, 0x6a48, 0x46);
  91         if (ret)
  92                 goto err;
  93         ret = zd1301_demod_wreg(dev, 0x6a4a, 0x15);
  94         if (ret)
  95                 goto err;
  96         ret = zd1301_demod_wreg(dev, 0x6a4b, 0x63);
  97         if (ret)
  98                 goto err;
  99         ret = zd1301_demod_wreg(dev, 0x6a5b, 0x99);
 100         if (ret)
 101                 goto err;
 102         ret = zd1301_demod_wreg(dev, 0x6a3b, 0x10);
 103         if (ret)
 104                 goto err;
 105         ret = zd1301_demod_wreg(dev, 0x6806, 0x01);
 106         if (ret)
 107                 goto err;
 108         ret = zd1301_demod_wreg(dev, 0x6a41, 0x08);
 109         if (ret)
 110                 goto err;
 111         ret = zd1301_demod_wreg(dev, 0x6a42, 0x46);
 112         if (ret)
 113                 goto err;
 114         ret = zd1301_demod_wreg(dev, 0x6a44, 0x14);
 115         if (ret)
 116                 goto err;
 117         ret = zd1301_demod_wreg(dev, 0x6a45, 0x67);
 118         if (ret)
 119                 goto err;
 120         ret = zd1301_demod_wreg(dev, 0x6a38, 0x00);
 121         if (ret)
 122                 goto err;
 123         ret = zd1301_demod_wreg(dev, 0x6a4c, 0x52);
 124         if (ret)
 125                 goto err;
 126         ret = zd1301_demod_wreg(dev, 0x6a49, 0x2a);
 127         if (ret)
 128                 goto err;
 129         ret = zd1301_demod_wreg(dev, 0x6840, 0x2e);
 130         if (ret)
 131                 goto err;
 132         ret = zd1301_demod_wreg(dev, 0x6a50, r6a50_val);
 133         if (ret)
 134                 goto err;
 135         ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
 136         if (ret)
 137                 goto err;
 138 
 139         return 0;
 140 err:
 141         dev_dbg(&pdev->dev, "failed=%d\n", ret);
 142         return ret;
 143 }
 144 
 145 static int zd1301_demod_sleep(struct dvb_frontend *fe)
 146 {
 147         struct zd1301_demod_dev *dev = fe->demodulator_priv;
 148         struct platform_device *pdev = dev->pdev;
 149         int ret;
 150 
 151         dev_dbg(&pdev->dev, "\n");
 152 
 153         ret = zd1301_demod_wreg(dev, 0x6a43, 0x70);
 154         if (ret)
 155                 goto err;
 156         ret = zd1301_demod_wreg(dev, 0x684e, 0x00);
 157         if (ret)
 158                 goto err;
 159         ret = zd1301_demod_wreg(dev, 0x6849, 0x00);
 160         if (ret)
 161                 goto err;
 162         ret = zd1301_demod_wreg(dev, 0x68e2, 0xd7);
 163         if (ret)
 164                 goto err;
 165         ret = zd1301_demod_wreg(dev, 0x68e0, 0x39);
 166         if (ret)
 167                 goto err;
 168         ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
 169         if (ret)
 170                 goto err;
 171 
 172         return 0;
 173 err:
 174         dev_dbg(&pdev->dev, "failed=%d\n", ret);
 175         return ret;
 176 }
 177 
 178 static int zd1301_demod_init(struct dvb_frontend *fe)
 179 {
 180         struct zd1301_demod_dev *dev = fe->demodulator_priv;
 181         struct platform_device *pdev = dev->pdev;
 182         int ret;
 183 
 184         dev_dbg(&pdev->dev, "\n");
 185 
 186         ret = zd1301_demod_wreg(dev, 0x6840, 0x26);
 187         if (ret)
 188                 goto err;
 189         ret = zd1301_demod_wreg(dev, 0x68e0, 0xff);
 190         if (ret)
 191                 goto err;
 192         ret = zd1301_demod_wreg(dev, 0x68e2, 0xd8);
 193         if (ret)
 194                 goto err;
 195         ret = zd1301_demod_wreg(dev, 0x6849, 0x4e);
 196         if (ret)
 197                 goto err;
 198         ret = zd1301_demod_wreg(dev, 0x684e, 0x01);
 199         if (ret)
 200                 goto err;
 201         ret = zd1301_demod_wreg(dev, 0x6a43, zd1301_demod_gain);
 202         if (ret)
 203                 goto err;
 204 
 205         return 0;
 206 err:
 207         dev_dbg(&pdev->dev, "failed=%d\n", ret);
 208         return ret;
 209 }
 210 
 211 static int zd1301_demod_get_tune_settings(struct dvb_frontend *fe,
 212                                           struct dvb_frontend_tune_settings *settings)
 213 {
 214         struct zd1301_demod_dev *dev = fe->demodulator_priv;
 215         struct platform_device *pdev = dev->pdev;
 216 
 217         dev_dbg(&pdev->dev, "\n");
 218 
 219         /* ~180ms seems to be enough */
 220         settings->min_delay_ms = 400;
 221 
 222         return 0;
 223 }
 224 
 225 static int zd1301_demod_read_status(struct dvb_frontend *fe,
 226                                     enum fe_status *status)
 227 {
 228         struct zd1301_demod_dev *dev = fe->demodulator_priv;
 229         struct platform_device *pdev = dev->pdev;
 230         int ret;
 231         u8 u8tmp;
 232 
 233         ret = zd1301_demod_rreg(dev, 0x6a24, &u8tmp);
 234         if (ret)
 235                 goto err;
 236         if (u8tmp > 0x00 && u8tmp < 0x20)
 237                 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
 238                           FE_HAS_SYNC | FE_HAS_LOCK;
 239         else
 240                 *status = 0;
 241 
 242         dev_dbg(&pdev->dev, "lock byte=%02x\n", u8tmp);
 243 
 244         /*
 245          * Interesting registers here are:
 246          * 0x6a05: get some gain value
 247          * 0x6a06: get about same gain value than set to 0x6a43
 248          * 0x6a07: get some gain value
 249          * 0x6a43: set gain value by driver
 250          * 0x6a24: get demod lock bits (FSM stage?)
 251          *
 252          * Driver should implement some kind of algorithm to calculate suitable
 253          * value for register 0x6a43, based likely values from register 0x6a05
 254          * and 0x6a07. Looks like gain register 0x6a43 value could be from
 255          * range 0x00 - 0x70.
 256          */
 257 
 258         if (dev->gain != zd1301_demod_gain) {
 259                 dev->gain = zd1301_demod_gain;
 260 
 261                 ret = zd1301_demod_wreg(dev, 0x6a43, dev->gain);
 262                 if (ret)
 263                         goto err;
 264         }
 265 
 266         return 0;
 267 err:
 268         dev_dbg(&pdev->dev, "failed=%d\n", ret);
 269         return ret;
 270 }
 271 
 272 static const struct dvb_frontend_ops zd1301_demod_ops = {
 273         .delsys = {SYS_DVBT},
 274         .info = {
 275                 .name = "ZyDAS ZD1301",
 276                 .caps = FE_CAN_FEC_1_2 |
 277                         FE_CAN_FEC_2_3 |
 278                         FE_CAN_FEC_3_4 |
 279                         FE_CAN_FEC_5_6 |
 280                         FE_CAN_FEC_7_8 |
 281                         FE_CAN_FEC_AUTO |
 282                         FE_CAN_QPSK |
 283                         FE_CAN_QAM_16 |
 284                         FE_CAN_QAM_64 |
 285                         FE_CAN_QAM_AUTO |
 286                         FE_CAN_TRANSMISSION_MODE_AUTO |
 287                         FE_CAN_GUARD_INTERVAL_AUTO |
 288                         FE_CAN_HIERARCHY_AUTO |
 289                         FE_CAN_MUTE_TS
 290         },
 291 
 292         .sleep = zd1301_demod_sleep,
 293         .init = zd1301_demod_init,
 294         .set_frontend = zd1301_demod_set_frontend,
 295         .get_tune_settings = zd1301_demod_get_tune_settings,
 296         .read_status = zd1301_demod_read_status,
 297 };
 298 
 299 struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *pdev)
 300 {
 301         struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
 302 
 303         dev_dbg(&pdev->dev, "\n");
 304 
 305         return &dev->frontend;
 306 }
 307 EXPORT_SYMBOL(zd1301_demod_get_dvb_frontend);
 308 
 309 static int zd1301_demod_i2c_master_xfer(struct i2c_adapter *adapter,
 310                                         struct i2c_msg msg[], int num)
 311 {
 312         struct zd1301_demod_dev *dev = i2c_get_adapdata(adapter);
 313         struct platform_device *pdev = dev->pdev;
 314         int ret, i;
 315         unsigned long timeout;
 316         u8 u8tmp;
 317 
 318         #define I2C_XFER_TIMEOUT 5
 319         #define ZD1301_IS_I2C_XFER_WRITE_READ(_msg, _num) \
 320                 (_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD))
 321         #define ZD1301_IS_I2C_XFER_WRITE(_msg, _num) \
 322                 (_num == 1 && !(_msg[0].flags & I2C_M_RD))
 323         #define ZD1301_IS_I2C_XFER_READ(_msg, _num) \
 324                 (_num == 1 && (_msg[0].flags & I2C_M_RD))
 325         if (ZD1301_IS_I2C_XFER_WRITE_READ(msg, num)) {
 326                 dev_dbg(&pdev->dev, "write&read msg[0].len=%u msg[1].len=%u\n",
 327                         msg[0].len, msg[1].len);
 328                 if (msg[0].len > 1 || msg[1].len > 8) {
 329                         ret = -EOPNOTSUPP;
 330                         goto err;
 331                 }
 332 
 333                 ret = zd1301_demod_wreg(dev, 0x6811, 0x80);
 334                 if (ret)
 335                         goto err;
 336                 ret = zd1301_demod_wreg(dev, 0x6812, 0x05);
 337                 if (ret)
 338                         goto err;
 339                 ret = zd1301_demod_wreg(dev, 0x6813, msg[1].addr << 1);
 340                 if (ret)
 341                         goto err;
 342                 ret = zd1301_demod_wreg(dev, 0x6801, msg[0].buf[0]);
 343                 if (ret)
 344                         goto err;
 345                 ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
 346                 if (ret)
 347                         goto err;
 348                 ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
 349                 if (ret)
 350                         goto err;
 351                 ret = zd1301_demod_wreg(dev, 0x6805, 0x00);
 352                 if (ret)
 353                         goto err;
 354                 ret = zd1301_demod_wreg(dev, 0x6804, msg[1].len);
 355                 if (ret)
 356                         goto err;
 357 
 358                 /* Poll xfer ready */
 359                 timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
 360                 for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
 361                         usleep_range(500, 800);
 362 
 363                         ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
 364                         if (ret)
 365                                 goto err;
 366                 }
 367 
 368                 for (i = 0; i < msg[1].len; i++) {
 369                         ret = zd1301_demod_rreg(dev, 0x0600 + i, &msg[1].buf[i]);
 370                         if (ret)
 371                                 goto err;
 372                 }
 373         } else if (ZD1301_IS_I2C_XFER_WRITE(msg, num)) {
 374                 dev_dbg(&pdev->dev, "write msg[0].len=%u\n", msg[0].len);
 375                 if (msg[0].len > 1 + 8) {
 376                         ret = -EOPNOTSUPP;
 377                         goto err;
 378                 }
 379 
 380                 ret = zd1301_demod_wreg(dev, 0x6811, 0x80);
 381                 if (ret)
 382                         goto err;
 383                 ret = zd1301_demod_wreg(dev, 0x6812, 0x01);
 384                 if (ret)
 385                         goto err;
 386                 ret = zd1301_demod_wreg(dev, 0x6813, msg[0].addr << 1);
 387                 if (ret)
 388                         goto err;
 389                 ret = zd1301_demod_wreg(dev, 0x6800, msg[0].buf[0]);
 390                 if (ret)
 391                         goto err;
 392                 ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
 393                 if (ret)
 394                         goto err;
 395                 ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
 396                 if (ret)
 397                         goto err;
 398 
 399                 for (i = 0; i < msg[0].len - 1; i++) {
 400                         ret = zd1301_demod_wreg(dev, 0x0600 + i, msg[0].buf[1 + i]);
 401                         if (ret)
 402                                 goto err;
 403                 }
 404 
 405                 ret = zd1301_demod_wreg(dev, 0x6805, 0x80);
 406                 if (ret)
 407                         goto err;
 408                 ret = zd1301_demod_wreg(dev, 0x6804, msg[0].len - 1);
 409                 if (ret)
 410                         goto err;
 411 
 412                 /* Poll xfer ready */
 413                 timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
 414                 for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
 415                         usleep_range(500, 800);
 416 
 417                         ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
 418                         if (ret)
 419                                 goto err;
 420                 }
 421         } else {
 422                 dev_dbg(&pdev->dev, "unknown msg[0].len=%u\n", msg[0].len);
 423                 ret = -EOPNOTSUPP;
 424                 goto err;
 425         }
 426 
 427         return num;
 428 err:
 429         dev_dbg(&pdev->dev, "failed=%d\n", ret);
 430         return ret;
 431 }
 432 
 433 static u32 zd1301_demod_i2c_functionality(struct i2c_adapter *adapter)
 434 {
 435         return I2C_FUNC_I2C;
 436 }
 437 
 438 static const struct i2c_algorithm zd1301_demod_i2c_algorithm = {
 439         .master_xfer   = zd1301_demod_i2c_master_xfer,
 440         .functionality = zd1301_demod_i2c_functionality,
 441 };
 442 
 443 struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *pdev)
 444 {
 445         struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
 446 
 447         dev_dbg(&pdev->dev, "\n");
 448 
 449         return &dev->adapter;
 450 }
 451 EXPORT_SYMBOL(zd1301_demod_get_i2c_adapter);
 452 
 453 /* Platform driver interface */
 454 static int zd1301_demod_probe(struct platform_device *pdev)
 455 {
 456         struct zd1301_demod_dev *dev;
 457         struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
 458         int ret;
 459 
 460         dev_dbg(&pdev->dev, "\n");
 461 
 462         if (!pdata) {
 463                 ret = -EINVAL;
 464                 dev_err(&pdev->dev, "cannot proceed without platform data\n");
 465                 goto err;
 466         }
 467         if (!pdev->dev.parent->driver) {
 468                 ret = -EINVAL;
 469                 dev_dbg(&pdev->dev, "no parent device\n");
 470                 goto err;
 471         }
 472 
 473         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 474         if (!dev) {
 475                 ret = -ENOMEM;
 476                 goto err;
 477         }
 478 
 479         /* Setup the state */
 480         dev->pdev = pdev;
 481         dev->gain = zd1301_demod_gain;
 482 
 483         /* Sleep */
 484         ret = zd1301_demod_wreg(dev, 0x6840, 0x21);
 485         if (ret)
 486                 goto err_kfree;
 487         ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
 488         if (ret)
 489                 goto err_kfree;
 490 
 491         /* Create I2C adapter */
 492         strscpy(dev->adapter.name, "ZyDAS ZD1301 demod",
 493                 sizeof(dev->adapter.name));
 494         dev->adapter.algo = &zd1301_demod_i2c_algorithm;
 495         dev->adapter.algo_data = NULL;
 496         dev->adapter.dev.parent = pdev->dev.parent;
 497         i2c_set_adapdata(&dev->adapter, dev);
 498         ret = i2c_add_adapter(&dev->adapter);
 499         if (ret) {
 500                 dev_err(&pdev->dev, "I2C adapter add failed %d\n", ret);
 501                 goto err_kfree;
 502         }
 503 
 504         /* Create dvb frontend */
 505         memcpy(&dev->frontend.ops, &zd1301_demod_ops, sizeof(dev->frontend.ops));
 506         dev->frontend.demodulator_priv = dev;
 507         platform_set_drvdata(pdev, dev);
 508         dev_info(&pdev->dev, "ZyDAS ZD1301 demod attached\n");
 509 
 510         return 0;
 511 err_kfree:
 512         kfree(dev);
 513 err:
 514         dev_dbg(&pdev->dev, "failed=%d\n", ret);
 515         return ret;
 516 }
 517 
 518 static int zd1301_demod_remove(struct platform_device *pdev)
 519 {
 520         struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
 521 
 522         dev_dbg(&pdev->dev, "\n");
 523 
 524         i2c_del_adapter(&dev->adapter);
 525         kfree(dev);
 526 
 527         return 0;
 528 }
 529 
 530 static struct platform_driver zd1301_demod_driver = {
 531         .driver = {
 532                 .name                = "zd1301_demod",
 533                 .suppress_bind_attrs = true,
 534         },
 535         .probe          = zd1301_demod_probe,
 536         .remove         = zd1301_demod_remove,
 537 };
 538 module_platform_driver(zd1301_demod_driver);
 539 
 540 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 541 MODULE_DESCRIPTION("ZyDAS ZD1301 demodulator driver");
 542 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */