root/drivers/media/tuners/msi001.c

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

DEFINITIONS

This source file includes following definitions.
  1. sd_to_msi001_dev
  2. msi001_wreg
  3. msi001_set_gain
  4. msi001_set_tuner
  5. msi001_standby
  6. msi001_g_tuner
  7. msi001_s_tuner
  8. msi001_g_frequency
  9. msi001_s_frequency
  10. msi001_enum_freq_bands
  11. msi001_s_ctrl
  12. msi001_probe
  13. msi001_remove

   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 
  14 static 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 
  30 struct 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 
  45 static inline struct msi001_dev *sd_to_msi001_dev(struct v4l2_subdev *sd)
  46 {
  47         return container_of(sd, struct msi001_dev, sd);
  48 }
  49 
  50 static 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 
  56 static 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;
  78 err:
  79         dev_dbg(&spi->dev, "failed %d\n", ret);
  80         return ret;
  81 };
  82 
  83 static 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;
 280 err:
 281         dev_dbg(&spi->dev, "failed %d\n", ret);
 282         return ret;
 283 }
 284 
 285 static 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 
 292 static 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 
 308 static 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 
 317 static 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 
 327 static 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 
 347 static 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 
 366 static 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 
 375 static const struct v4l2_subdev_ops msi001_ops = {
 376         .tuner                    = &msi001_tuner_ops,
 377 };
 378 
 379 static 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 
 418 static const struct v4l2_ctrl_ops msi001_ctrl_ops = {
 419         .s_ctrl                   = msi001_s_ctrl,
 420 };
 421 
 422 static 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;
 461 err_ctrl_handler_free:
 462         v4l2_ctrl_handler_free(&dev->hdl);
 463         kfree(dev);
 464 err:
 465         return ret;
 466 }
 467 
 468 static 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 
 485 static const struct spi_device_id msi001_id_table[] = {
 486         {"msi001", 0},
 487         {}
 488 };
 489 MODULE_DEVICE_TABLE(spi, msi001_id_table);
 490 
 491 static 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 };
 500 module_spi_driver(msi001_driver);
 501 
 502 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
 503 MODULE_DESCRIPTION("Mirics MSi001");
 504 MODULE_LICENSE("GPL");

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