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