Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 // For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
0003 // I2C address is always 0xC0.
0004 //
0005 // Copyright (c) 2005 Mauro Carvalho Chehab <mchehab@kernel.org>
0006 //
0007 // tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
0008 // from their contributions on DScaler.
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #include <linux/i2c.h>
0013 #include <linux/slab.h>
0014 #include <linux/delay.h>
0015 #include <linux/videodev2.h>
0016 #include "tuner-i2c.h"
0017 #include "tea5767.h"
0018 
0019 static int debug;
0020 module_param(debug, int, 0644);
0021 MODULE_PARM_DESC(debug, "enable verbose debug messages");
0022 
0023 /*****************************************************************************/
0024 
0025 struct tea5767_priv {
0026     struct tuner_i2c_props  i2c_props;
0027     u32         frequency;
0028     struct tea5767_ctrl ctrl;
0029 };
0030 
0031 /*****************************************************************************/
0032 
0033 /******************************
0034  * Write mode register values *
0035  ******************************/
0036 
0037 /* First register */
0038 #define TEA5767_MUTE        0x80    /* Mutes output */
0039 #define TEA5767_SEARCH      0x40    /* Activates station search */
0040 /* Bits 0-5 for divider MSB */
0041 
0042 /* Second register */
0043 /* Bits 0-7 for divider LSB */
0044 
0045 /* Third register */
0046 
0047 /* Station search from botton to up */
0048 #define TEA5767_SEARCH_UP   0x80
0049 
0050 /* Searches with ADC output = 10 */
0051 #define TEA5767_SRCH_HIGH_LVL   0x60
0052 
0053 /* Searches with ADC output = 10 */
0054 #define TEA5767_SRCH_MID_LVL    0x40
0055 
0056 /* Searches with ADC output = 5 */
0057 #define TEA5767_SRCH_LOW_LVL    0x20
0058 
0059 /* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
0060 #define TEA5767_HIGH_LO_INJECT  0x10
0061 
0062 /* Disable stereo */
0063 #define TEA5767_MONO        0x08
0064 
0065 /* Disable right channel and turns to mono */
0066 #define TEA5767_MUTE_RIGHT  0x04
0067 
0068 /* Disable left channel and turns to mono */
0069 #define TEA5767_MUTE_LEFT   0x02
0070 
0071 #define TEA5767_PORT1_HIGH  0x01
0072 
0073 /* Fourth register */
0074 #define TEA5767_PORT2_HIGH  0x80
0075 /* Chips stops working. Only I2C bus remains on */
0076 #define TEA5767_STDBY       0x40
0077 
0078 /* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
0079 #define TEA5767_JAPAN_BAND  0x20
0080 
0081 /* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
0082 #define TEA5767_XTAL_32768  0x10
0083 
0084 /* Cuts weak signals */
0085 #define TEA5767_SOFT_MUTE   0x08
0086 
0087 /* Activates high cut control */
0088 #define TEA5767_HIGH_CUT_CTRL   0x04
0089 
0090 /* Activates stereo noise control */
0091 #define TEA5767_ST_NOISE_CTL    0x02
0092 
0093 /* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
0094 #define TEA5767_SRCH_IND    0x01
0095 
0096 /* Fifth register */
0097 
0098 /* By activating, it will use Xtal at 13 MHz as reference for divider */
0099 #define TEA5767_PLLREF_ENABLE   0x80
0100 
0101 /* By activating, deemphasis=50, or else, deemphasis of 50us */
0102 #define TEA5767_DEEMPH_75   0X40
0103 
0104 /*****************************
0105  * Read mode register values *
0106  *****************************/
0107 
0108 /* First register */
0109 #define TEA5767_READY_FLAG_MASK 0x80
0110 #define TEA5767_BAND_LIMIT_MASK 0X40
0111 /* Bits 0-5 for divider MSB after search or preset */
0112 
0113 /* Second register */
0114 /* Bits 0-7 for divider LSB after search or preset */
0115 
0116 /* Third register */
0117 #define TEA5767_STEREO_MASK 0x80
0118 #define TEA5767_IF_CNTR_MASK    0x7f
0119 
0120 /* Fourth register */
0121 #define TEA5767_ADC_LEVEL_MASK  0xf0
0122 
0123 /* should be 0 */
0124 #define TEA5767_CHIP_ID_MASK    0x0f
0125 
0126 /* Fifth register */
0127 /* Reserved for future extensions */
0128 #define TEA5767_RESERVED_MASK   0xff
0129 
0130 /*****************************************************************************/
0131 
0132 static void tea5767_status_dump(struct tea5767_priv *priv,
0133                 unsigned char *buffer)
0134 {
0135     unsigned int div, frq;
0136 
0137     if (TEA5767_READY_FLAG_MASK & buffer[0])
0138         tuner_info("Ready Flag ON\n");
0139     else
0140         tuner_info("Ready Flag OFF\n");
0141 
0142     if (TEA5767_BAND_LIMIT_MASK & buffer[0])
0143         tuner_info("Tuner at band limit\n");
0144     else
0145         tuner_info("Tuner not at band limit\n");
0146 
0147     div = ((buffer[0] & 0x3f) << 8) | buffer[1];
0148 
0149     switch (priv->ctrl.xtal_freq) {
0150     case TEA5767_HIGH_LO_13MHz:
0151         frq = (div * 50000 - 700000 - 225000) / 4;  /* Freq in KHz */
0152         break;
0153     case TEA5767_LOW_LO_13MHz:
0154         frq = (div * 50000 + 700000 + 225000) / 4;  /* Freq in KHz */
0155         break;
0156     case TEA5767_LOW_LO_32768:
0157         frq = (div * 32768 + 700000 + 225000) / 4;  /* Freq in KHz */
0158         break;
0159     case TEA5767_HIGH_LO_32768:
0160     default:
0161         frq = (div * 32768 - 700000 - 225000) / 4;  /* Freq in KHz */
0162         break;
0163     }
0164     buffer[0] = (div >> 8) & 0x3f;
0165     buffer[1] = div & 0xff;
0166 
0167     tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n",
0168            frq / 1000, frq % 1000, div);
0169 
0170     if (TEA5767_STEREO_MASK & buffer[2])
0171         tuner_info("Stereo\n");
0172     else
0173         tuner_info("Mono\n");
0174 
0175     tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
0176 
0177     tuner_info("ADC Level = %d\n",
0178            (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
0179 
0180     tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
0181 
0182     tuner_info("Reserved = 0x%02x\n",
0183            (buffer[4] & TEA5767_RESERVED_MASK));
0184 }
0185 
0186 /* Freq should be specifyed at 62.5 Hz */
0187 static int set_radio_freq(struct dvb_frontend *fe,
0188               struct analog_parameters *params)
0189 {
0190     struct tea5767_priv *priv = fe->tuner_priv;
0191     unsigned int frq = params->frequency;
0192     unsigned char buffer[5];
0193     unsigned div;
0194     int rc;
0195 
0196     tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
0197 
0198     buffer[2] = 0;
0199 
0200     if (priv->ctrl.port1)
0201         buffer[2] |= TEA5767_PORT1_HIGH;
0202 
0203     if (params->audmode == V4L2_TUNER_MODE_MONO) {
0204         tuner_dbg("TEA5767 set to mono\n");
0205         buffer[2] |= TEA5767_MONO;
0206     } else {
0207         tuner_dbg("TEA5767 set to stereo\n");
0208     }
0209 
0210 
0211     buffer[3] = 0;
0212 
0213     if (priv->ctrl.port2)
0214         buffer[3] |= TEA5767_PORT2_HIGH;
0215 
0216     if (priv->ctrl.high_cut)
0217         buffer[3] |= TEA5767_HIGH_CUT_CTRL;
0218 
0219     if (priv->ctrl.st_noise)
0220         buffer[3] |= TEA5767_ST_NOISE_CTL;
0221 
0222     if (priv->ctrl.soft_mute)
0223         buffer[3] |= TEA5767_SOFT_MUTE;
0224 
0225     if (priv->ctrl.japan_band)
0226         buffer[3] |= TEA5767_JAPAN_BAND;
0227 
0228     buffer[4] = 0;
0229 
0230     if (priv->ctrl.deemph_75)
0231         buffer[4] |= TEA5767_DEEMPH_75;
0232 
0233     if (priv->ctrl.pllref)
0234         buffer[4] |= TEA5767_PLLREF_ENABLE;
0235 
0236 
0237     /* Rounds freq to next decimal value - for 62.5 KHz step */
0238     /* frq = 20*(frq/16)+radio_frq[frq%16]; */
0239 
0240     switch (priv->ctrl.xtal_freq) {
0241     case TEA5767_HIGH_LO_13MHz:
0242         tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n");
0243         buffer[2] |= TEA5767_HIGH_LO_INJECT;
0244         div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000;
0245         break;
0246     case TEA5767_LOW_LO_13MHz:
0247         tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n");
0248 
0249         div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000;
0250         break;
0251     case TEA5767_LOW_LO_32768:
0252         tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n");
0253         buffer[3] |= TEA5767_XTAL_32768;
0254         /* const 700=4000*175 Khz - to adjust freq to right value */
0255         div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15;
0256         break;
0257     case TEA5767_HIGH_LO_32768:
0258     default:
0259         tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n");
0260 
0261         buffer[2] |= TEA5767_HIGH_LO_INJECT;
0262         buffer[3] |= TEA5767_XTAL_32768;
0263         div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
0264         break;
0265     }
0266     buffer[0] = (div >> 8) & 0x3f;
0267     buffer[1] = div & 0xff;
0268 
0269     if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
0270         tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
0271 
0272     if (debug) {
0273         if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
0274             tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
0275         else
0276             tea5767_status_dump(priv, buffer);
0277     }
0278 
0279     priv->frequency = frq * 125 / 2;
0280 
0281     return 0;
0282 }
0283 
0284 static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
0285 {
0286     struct tea5767_priv *priv = fe->tuner_priv;
0287     int rc;
0288 
0289     memset(buffer, 0, 5);
0290     if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
0291         tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
0292         return -EREMOTEIO;
0293     }
0294 
0295     return 0;
0296 }
0297 
0298 static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
0299 {
0300     struct tea5767_priv *priv = fe->tuner_priv;
0301 
0302     int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
0303 
0304     tuner_dbg("Signal strength: %d\n", signal);
0305 
0306     return signal;
0307 }
0308 
0309 static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
0310 {
0311     struct tea5767_priv *priv = fe->tuner_priv;
0312 
0313     int stereo = buffer[2] & TEA5767_STEREO_MASK;
0314 
0315     tuner_dbg("Radio ST GET = %02x\n", stereo);
0316 
0317     return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
0318 }
0319 
0320 static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
0321 {
0322     unsigned char buffer[5];
0323 
0324     *status = 0;
0325 
0326     if (0 == tea5767_read_status(fe, buffer)) {
0327         if (tea5767_signal(fe, buffer))
0328             *status = TUNER_STATUS_LOCKED;
0329         if (tea5767_stereo(fe, buffer))
0330             *status |= TUNER_STATUS_STEREO;
0331     }
0332 
0333     return 0;
0334 }
0335 
0336 static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
0337 {
0338     unsigned char buffer[5];
0339 
0340     *strength = 0;
0341 
0342     if (0 == tea5767_read_status(fe, buffer))
0343         *strength = tea5767_signal(fe, buffer);
0344 
0345     return 0;
0346 }
0347 
0348 static int tea5767_standby(struct dvb_frontend *fe)
0349 {
0350     unsigned char buffer[5];
0351     struct tea5767_priv *priv = fe->tuner_priv;
0352     unsigned div, rc;
0353 
0354     div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
0355     buffer[0] = (div >> 8) & 0x3f;
0356     buffer[1] = div & 0xff;
0357     buffer[2] = TEA5767_PORT1_HIGH;
0358     buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
0359             TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
0360     buffer[4] = 0;
0361 
0362     if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
0363         tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
0364 
0365     return 0;
0366 }
0367 
0368 int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
0369 {
0370     struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
0371     unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
0372 
0373     int rc;
0374 
0375     if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
0376         pr_warn("It is not a TEA5767. Received %i bytes.\n", rc);
0377         return -EINVAL;
0378     }
0379 
0380     /* If all bytes are the same then it's a TV tuner and not a tea5767 */
0381     if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
0382         buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
0383         pr_warn("All bytes are equal. It is not a TEA5767\n");
0384         return -EINVAL;
0385     }
0386 
0387     /*  Status bytes:
0388      *  Byte 4: bit 3:1 : CI (Chip Identification) == 0
0389      *          bit 0   : internally set to 0
0390      *  Byte 5: bit 7:0 : == 0
0391      */
0392     if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
0393         pr_warn("Chip ID is not zero. It is not a TEA5767\n");
0394         return -EINVAL;
0395     }
0396 
0397 
0398     return 0;
0399 }
0400 
0401 static void tea5767_release(struct dvb_frontend *fe)
0402 {
0403     kfree(fe->tuner_priv);
0404     fe->tuner_priv = NULL;
0405 }
0406 
0407 static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0408 {
0409     struct tea5767_priv *priv = fe->tuner_priv;
0410     *frequency = priv->frequency;
0411 
0412     return 0;
0413 }
0414 
0415 static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg)
0416 {
0417     struct tea5767_priv *priv = fe->tuner_priv;
0418 
0419     memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl));
0420 
0421     return 0;
0422 }
0423 
0424 static const struct dvb_tuner_ops tea5767_tuner_ops = {
0425     .info = {
0426         .name           = "tea5767", // Philips TEA5767HN FM Radio
0427     },
0428 
0429     .set_analog_params = set_radio_freq,
0430     .set_config    = tea5767_set_config,
0431     .sleep             = tea5767_standby,
0432     .release           = tea5767_release,
0433     .get_frequency     = tea5767_get_frequency,
0434     .get_status        = tea5767_get_status,
0435     .get_rf_strength   = tea5767_get_rf_strength,
0436 };
0437 
0438 struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
0439                     struct i2c_adapter* i2c_adap,
0440                     u8 i2c_addr)
0441 {
0442     struct tea5767_priv *priv = NULL;
0443 
0444     priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
0445     if (priv == NULL)
0446         return NULL;
0447     fe->tuner_priv = priv;
0448 
0449     priv->i2c_props.addr  = i2c_addr;
0450     priv->i2c_props.adap  = i2c_adap;
0451     priv->i2c_props.name  = "tea5767";
0452 
0453     priv->ctrl.xtal_freq  = TEA5767_HIGH_LO_32768;
0454     priv->ctrl.port1      = 1;
0455     priv->ctrl.port2      = 1;
0456     priv->ctrl.high_cut   = 1;
0457     priv->ctrl.st_noise   = 1;
0458     priv->ctrl.japan_band = 1;
0459 
0460     memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops,
0461            sizeof(struct dvb_tuner_ops));
0462 
0463     tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio");
0464 
0465     return fe;
0466 }
0467 
0468 EXPORT_SYMBOL_GPL(tea5767_attach);
0469 EXPORT_SYMBOL_GPL(tea5767_autodetection);
0470 
0471 MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
0472 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@kernel.org>");
0473 MODULE_LICENSE("GPL v2");