linux/drivers/media/tuners/msi001.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Mirics MSi001 silicon tuner driver
   4 *
   5 * Copyright (C) 2013 Antti Palosaari <crope@iki.fi>
   6 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/gcd.h>
  11#include <media/v4l2-device.h>
  12#include <media/v4l2-ctrls.h>
  13
  14static const struct v4l2_frequency_band bands[] = {
  15        {
  16                .type = V4L2_TUNER_RF,
  17                .index = 0,
  18                .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
  19                .rangelow   =   49000000,
  20                .rangehigh  =  263000000,
  21        }, {
  22                .type = V4L2_TUNER_RF,
  23                .index = 1,
  24                .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
  25                .rangelow   =  390000000,
  26                .rangehigh  =  960000000,
  27        },
  28};
  29
  30struct msi001_dev {
  31        struct spi_device *spi;
  32        struct v4l2_subdev sd;
  33
  34        /* Controls */
  35        struct v4l2_ctrl_handler hdl;
  36        struct v4l2_ctrl *bandwidth_auto;
  37        struct v4l2_ctrl *bandwidth;
  38        struct v4l2_ctrl *lna_gain;
  39        struct v4l2_ctrl *mixer_gain;
  40        struct v4l2_ctrl *if_gain;
  41
  42        unsigned int f_tuner;
  43};
  44
  45static inline struct msi001_dev *sd_to_msi001_dev(struct v4l2_subdev *sd)
  46{
  47        return container_of(sd, struct msi001_dev, sd);
  48}
  49
  50static int msi001_wreg(struct msi001_dev *dev, u32 data)
  51{
  52        /* Register format: 4 bits addr + 20 bits value */
  53        return spi_write(dev->spi, &data, 3);
  54};
  55
  56static int msi001_set_gain(struct msi001_dev *dev, int lna_gain, int mixer_gain,
  57                           int if_gain)
  58{
  59        struct spi_device *spi = dev->spi;
  60        int ret;
  61        u32 reg;
  62
  63        dev_dbg(&spi->dev, "lna=%d mixer=%d if=%d\n",
  64                lna_gain, mixer_gain, if_gain);
  65
  66        reg = 1 << 0;
  67        reg |= (59 - if_gain) << 4;
  68        reg |= 0 << 10;
  69        reg |= (1 - mixer_gain) << 12;
  70        reg |= (1 - lna_gain) << 13;
  71        reg |= 4 << 14;
  72        reg |= 0 << 17;
  73        ret = msi001_wreg(dev, reg);
  74        if (ret)
  75                goto err;
  76
  77        return 0;
  78err:
  79        dev_dbg(&spi->dev, "failed %d\n", ret);
  80        return ret;
  81};
  82
  83static int msi001_set_tuner(struct msi001_dev *dev)
  84{
  85        struct spi_device *spi = dev->spi;
  86        int ret, i;
  87        unsigned int uitmp, div_n, k, k_thresh, k_frac, div_lo, f_if1;
  88        u32 reg;
  89        u64 f_vco;
  90        u8 mode, filter_mode;
  91
  92        static const struct {
  93                u32 rf;
  94                u8 mode;
  95                u8 div_lo;
  96        } band_lut[] = {
  97                { 50000000, 0xe1, 16}, /* AM_MODE2, antenna 2 */
  98                {108000000, 0x42, 32}, /* VHF_MODE */
  99                {330000000, 0x44, 16}, /* B3_MODE */
 100                {960000000, 0x48,  4}, /* B45_MODE */
 101                {      ~0U, 0x50,  2}, /* BL_MODE */
 102        };
 103        static const struct {
 104                u32 freq;
 105                u8 filter_mode;
 106        } if_freq_lut[] = {
 107                {      0, 0x03}, /* Zero IF */
 108                { 450000, 0x02}, /* 450 kHz IF */
 109                {1620000, 0x01}, /* 1.62 MHz IF */
 110                {2048000, 0x00}, /* 2.048 MHz IF */
 111        };
 112        static const struct {
 113                u32 freq;
 114                u8 val;
 115        } bandwidth_lut[] = {
 116                { 200000, 0x00}, /* 200 kHz */
 117                { 300000, 0x01}, /* 300 kHz */
 118                { 600000, 0x02}, /* 600 kHz */
 119                {1536000, 0x03}, /* 1.536 MHz */
 120                {5000000, 0x04}, /* 5 MHz */
 121                {6000000, 0x05}, /* 6 MHz */
 122                {7000000, 0x06}, /* 7 MHz */
 123                {8000000, 0x07}, /* 8 MHz */
 124        };
 125
 126        unsigned int f_rf = dev->f_tuner;
 127
 128        /*
 129         * bandwidth (Hz)
 130         * 200000, 300000, 600000, 1536000, 5000000, 6000000, 7000000, 8000000
 131         */
 132        unsigned int bandwidth;
 133
 134        /*
 135         * intermediate frequency (Hz)
 136         * 0, 450000, 1620000, 2048000
 137         */
 138        unsigned int f_if = 0;
 139        #define F_REF 24000000
 140        #define DIV_PRE_N 4
 141        #define F_VCO_STEP div_lo
 142
 143        dev_dbg(&spi->dev, "f_rf=%d f_if=%d\n", f_rf, f_if);
 144
 145        for (i = 0; i < ARRAY_SIZE(band_lut); i++) {
 146                if (f_rf <= band_lut[i].rf) {
 147                        mode = band_lut[i].mode;
 148                        div_lo = band_lut[i].div_lo;
 149                        break;
 150                }
 151        }
 152        if (i == ARRAY_SIZE(band_lut)) {
 153                ret = -EINVAL;
 154                goto err;
 155        }
 156
 157        /* AM_MODE is upconverted */
 158        if ((mode >> 0) & 0x1)
 159                f_if1 =  5 * F_REF;
 160        else
 161                f_if1 =  0;
 162
 163        for (i = 0; i < ARRAY_SIZE(if_freq_lut); i++) {
 164                if (f_if == if_freq_lut[i].freq) {
 165                        filter_mode = if_freq_lut[i].filter_mode;
 166                        break;
 167                }
 168        }
 169        if (i == ARRAY_SIZE(if_freq_lut)) {
 170                ret = -EINVAL;
 171                goto err;
 172        }
 173
 174        /* filters */
 175        bandwidth = dev->bandwidth->val;
 176        bandwidth = clamp(bandwidth, 200000U, 8000000U);
 177
 178        for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {
 179                if (bandwidth <= bandwidth_lut[i].freq) {
 180                        bandwidth = bandwidth_lut[i].val;
 181                        break;
 182                }
 183        }
 184        if (i == ARRAY_SIZE(bandwidth_lut)) {
 185                ret = -EINVAL;
 186                goto err;
 187        }
 188
 189        dev->bandwidth->val = bandwidth_lut[i].freq;
 190
 191        dev_dbg(&spi->dev, "bandwidth selected=%d\n", bandwidth_lut[i].freq);
 192
 193        /*
 194         * Fractional-N synthesizer
 195         *
 196         *           +---------------------------------------+
 197         *           v                                       |
 198         *  Fref   +----+     +-------+         +----+     +------+     +---+
 199         * ------> | PD | --> |  VCO  | ------> | /4 | --> | /N.F | <-- | K |
 200         *         +----+     +-------+         +----+     +------+     +---+
 201         *                      |
 202         *                      |
 203         *                      v
 204         *                    +-------+  Fout
 205         *                    | /Rout | ------>
 206         *                    +-------+
 207         */
 208
 209        /* Calculate PLL integer and fractional control word. */
 210        f_vco = (u64) (f_rf + f_if + f_if1) * div_lo;
 211        div_n = div_u64_rem(f_vco, DIV_PRE_N * F_REF, &k);
 212        k_thresh = (DIV_PRE_N * F_REF) / F_VCO_STEP;
 213        k_frac = div_u64((u64) k * k_thresh, (DIV_PRE_N * F_REF));
 214
 215        /* Find out greatest common divisor and divide to smaller. */
 216        uitmp = gcd(k_thresh, k_frac);
 217        k_thresh /= uitmp;
 218        k_frac /= uitmp;
 219
 220        /* Force divide to reg max. Resolution will be reduced. */
 221        uitmp = DIV_ROUND_UP(k_thresh, 4095);
 222        k_thresh = DIV_ROUND_CLOSEST(k_thresh, uitmp);
 223        k_frac = DIV_ROUND_CLOSEST(k_frac, uitmp);
 224
 225        /* Calculate real RF set. */
 226        uitmp = (unsigned int) F_REF * DIV_PRE_N * div_n;
 227        uitmp += (unsigned int) F_REF * DIV_PRE_N * k_frac / k_thresh;
 228        uitmp /= div_lo;
 229
 230        dev_dbg(&spi->dev,
 231                "f_rf=%u:%u f_vco=%llu div_n=%u k_thresh=%u k_frac=%u div_lo=%u\n",
 232                f_rf, uitmp, f_vco, div_n, k_thresh, k_frac, div_lo);
 233
 234        ret = msi001_wreg(dev, 0x00000e);
 235        if (ret)
 236                goto err;
 237
 238        ret = msi001_wreg(dev, 0x000003);
 239        if (ret)
 240                goto err;
 241
 242        reg = 0 << 0;
 243        reg |= mode << 4;
 244        reg |= filter_mode << 12;
 245        reg |= bandwidth << 14;
 246        reg |= 0x02 << 17;
 247        reg |= 0x00 << 20;
 248        ret = msi001_wreg(dev, reg);
 249        if (ret)
 250                goto err;
 251
 252        reg = 5 << 0;
 253        reg |= k_thresh << 4;
 254        reg |= 1 << 19;
 255        reg |= 1 << 21;
 256        ret = msi001_wreg(dev, reg);
 257        if (ret)
 258                goto err;
 259
 260        reg = 2 << 0;
 261        reg |= k_frac << 4;
 262        reg |= div_n << 16;
 263        ret = msi001_wreg(dev, reg);
 264        if (ret)
 265                goto err;
 266
 267        ret = msi001_set_gain(dev, dev->lna_gain->cur.val,
 268                              dev->mixer_gain->cur.val, dev->if_gain->cur.val);
 269        if (ret)
 270                goto err;
 271
 272        reg = 6 << 0;
 273        reg |= 63 << 4;
 274        reg |= 4095 << 10;
 275        ret = msi001_wreg(dev, reg);
 276        if (ret)
 277                goto err;
 278
 279        return 0;
 280err:
 281        dev_dbg(&spi->dev, "failed %d\n", ret);
 282        return ret;
 283}
 284
 285static int msi001_standby(struct v4l2_subdev *sd)
 286{
 287        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 288
 289        return msi001_wreg(dev, 0x000000);
 290}
 291
 292static int msi001_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *v)
 293{
 294        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 295        struct spi_device *spi = dev->spi;
 296
 297        dev_dbg(&spi->dev, "index=%d\n", v->index);
 298
 299        strscpy(v->name, "Mirics MSi001", sizeof(v->name));
 300        v->type = V4L2_TUNER_RF;
 301        v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
 302        v->rangelow =    49000000;
 303        v->rangehigh =  960000000;
 304
 305        return 0;
 306}
 307
 308static int msi001_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *v)
 309{
 310        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 311        struct spi_device *spi = dev->spi;
 312
 313        dev_dbg(&spi->dev, "index=%d\n", v->index);
 314        return 0;
 315}
 316
 317static int msi001_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 318{
 319        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 320        struct spi_device *spi = dev->spi;
 321
 322        dev_dbg(&spi->dev, "tuner=%d\n", f->tuner);
 323        f->frequency = dev->f_tuner;
 324        return 0;
 325}
 326
 327static int msi001_s_frequency(struct v4l2_subdev *sd,
 328                              const struct v4l2_frequency *f)
 329{
 330        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 331        struct spi_device *spi = dev->spi;
 332        unsigned int band;
 333
 334        dev_dbg(&spi->dev, "tuner=%d type=%d frequency=%u\n",
 335                f->tuner, f->type, f->frequency);
 336
 337        if (f->frequency < ((bands[0].rangehigh + bands[1].rangelow) / 2))
 338                band = 0;
 339        else
 340                band = 1;
 341        dev->f_tuner = clamp_t(unsigned int, f->frequency,
 342                               bands[band].rangelow, bands[band].rangehigh);
 343
 344        return msi001_set_tuner(dev);
 345}
 346
 347static int msi001_enum_freq_bands(struct v4l2_subdev *sd,
 348                                  struct v4l2_frequency_band *band)
 349{
 350        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 351        struct spi_device *spi = dev->spi;
 352
 353        dev_dbg(&spi->dev, "tuner=%d type=%d index=%d\n",
 354                band->tuner, band->type, band->index);
 355
 356        if (band->index >= ARRAY_SIZE(bands))
 357                return -EINVAL;
 358
 359        band->capability = bands[band->index].capability;
 360        band->rangelow = bands[band->index].rangelow;
 361        band->rangehigh = bands[band->index].rangehigh;
 362
 363        return 0;
 364}
 365
 366static const struct v4l2_subdev_tuner_ops msi001_tuner_ops = {
 367        .standby                  = msi001_standby,
 368        .g_tuner                  = msi001_g_tuner,
 369        .s_tuner                  = msi001_s_tuner,
 370        .g_frequency              = msi001_g_frequency,
 371        .s_frequency              = msi001_s_frequency,
 372        .enum_freq_bands          = msi001_enum_freq_bands,
 373};
 374
 375static const struct v4l2_subdev_ops msi001_ops = {
 376        .tuner                    = &msi001_tuner_ops,
 377};
 378
 379static int msi001_s_ctrl(struct v4l2_ctrl *ctrl)
 380{
 381        struct msi001_dev *dev = container_of(ctrl->handler, struct msi001_dev, hdl);
 382        struct spi_device *spi = dev->spi;
 383
 384        int ret;
 385
 386        dev_dbg(&spi->dev, "id=%d name=%s val=%d min=%lld max=%lld step=%lld\n",
 387                ctrl->id, ctrl->name, ctrl->val, ctrl->minimum, ctrl->maximum,
 388                ctrl->step);
 389
 390        switch (ctrl->id) {
 391        case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
 392        case V4L2_CID_RF_TUNER_BANDWIDTH:
 393                ret = msi001_set_tuner(dev);
 394                break;
 395        case  V4L2_CID_RF_TUNER_LNA_GAIN:
 396                ret = msi001_set_gain(dev, dev->lna_gain->val,
 397                                      dev->mixer_gain->cur.val,
 398                                      dev->if_gain->cur.val);
 399                break;
 400        case  V4L2_CID_RF_TUNER_MIXER_GAIN:
 401                ret = msi001_set_gain(dev, dev->lna_gain->cur.val,
 402                                      dev->mixer_gain->val,
 403                                      dev->if_gain->cur.val);
 404                break;
 405        case  V4L2_CID_RF_TUNER_IF_GAIN:
 406                ret = msi001_set_gain(dev, dev->lna_gain->cur.val,
 407                                      dev->mixer_gain->cur.val,
 408                                      dev->if_gain->val);
 409                break;
 410        default:
 411                dev_dbg(&spi->dev, "unknown control %d\n", ctrl->id);
 412                ret = -EINVAL;
 413        }
 414
 415        return ret;
 416}
 417
 418static const struct v4l2_ctrl_ops msi001_ctrl_ops = {
 419        .s_ctrl                   = msi001_s_ctrl,
 420};
 421
 422static int msi001_probe(struct spi_device *spi)
 423{
 424        struct msi001_dev *dev;
 425        int ret;
 426
 427        dev_dbg(&spi->dev, "\n");
 428
 429        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 430        if (!dev) {
 431                ret = -ENOMEM;
 432                goto err;
 433        }
 434
 435        dev->spi = spi;
 436        dev->f_tuner = bands[0].rangelow;
 437        v4l2_spi_subdev_init(&dev->sd, spi, &msi001_ops);
 438
 439        /* Register controls */
 440        v4l2_ctrl_handler_init(&dev->hdl, 5);
 441        dev->bandwidth_auto = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
 442                        V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1);
 443        dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
 444                        V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000);
 445        v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false);
 446        dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
 447                        V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1);
 448        dev->mixer_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
 449                        V4L2_CID_RF_TUNER_MIXER_GAIN, 0, 1, 1, 1);
 450        dev->if_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops,
 451                        V4L2_CID_RF_TUNER_IF_GAIN, 0, 59, 1, 0);
 452        if (dev->hdl.error) {
 453                ret = dev->hdl.error;
 454                dev_err(&spi->dev, "Could not initialize controls\n");
 455                /* control init failed, free handler */
 456                goto err_ctrl_handler_free;
 457        }
 458
 459        dev->sd.ctrl_handler = &dev->hdl;
 460        return 0;
 461err_ctrl_handler_free:
 462        v4l2_ctrl_handler_free(&dev->hdl);
 463        kfree(dev);
 464err:
 465        return ret;
 466}
 467
 468static int msi001_remove(struct spi_device *spi)
 469{
 470        struct v4l2_subdev *sd = spi_get_drvdata(spi);
 471        struct msi001_dev *dev = sd_to_msi001_dev(sd);
 472
 473        dev_dbg(&spi->dev, "\n");
 474
 475        /*
 476         * Registered by v4l2_spi_new_subdev() from master driver, but we must
 477         * unregister it from here. Weird.
 478         */
 479        v4l2_device_unregister_subdev(&dev->sd);
 480        v4l2_ctrl_handler_free(&dev->hdl);
 481        kfree(dev);
 482        return 0;
 483}
 484
 485static const struct spi_device_id msi001_id_table[] = {
 486        {"msi001", 0},
 487        {}
 488};
 489MODULE_DEVICE_TABLE(spi, msi001_id_table);
 490
 491static struct spi_driver msi001_driver = {
 492        .driver = {
 493                .name   = "msi001",
 494                .suppress_bind_attrs = true,
 495        },
 496        .probe          = msi001_probe,
 497        .remove         = msi001_remove,
 498        .id_table       = msi001_id_table,
 499};
 500module_spi_driver(msi001_driver);
 501
 502MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 503MODULE_DESCRIPTION("Mirics MSi001");
 504MODULE_LICENSE("GPL");
 505