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

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

DEFINITIONS

This source file includes following definitions.
  1. stb6000_release
  2. stb6000_sleep
  3. stb6000_set_params
  4. stb6000_get_frequency
  5. stb6000_attach

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2   /*
   3      Driver for ST STB6000 DVBS Silicon tuner
   4 
   5      Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
   6 
   7 
   8   */
   9 
  10 #include <linux/slab.h>
  11 #include <linux/module.h>
  12 #include <linux/dvb/frontend.h>
  13 #include <asm/types.h>
  14 
  15 #include "stb6000.h"
  16 
  17 static int debug;
  18 #define dprintk(args...) \
  19         do { \
  20                 if (debug) \
  21                         printk(KERN_DEBUG "stb6000: " args); \
  22         } while (0)
  23 
  24 struct stb6000_priv {
  25         /* i2c details */
  26         int i2c_address;
  27         struct i2c_adapter *i2c;
  28         u32 frequency;
  29 };
  30 
  31 static void stb6000_release(struct dvb_frontend *fe)
  32 {
  33         kfree(fe->tuner_priv);
  34         fe->tuner_priv = NULL;
  35 }
  36 
  37 static int stb6000_sleep(struct dvb_frontend *fe)
  38 {
  39         struct stb6000_priv *priv = fe->tuner_priv;
  40         int ret;
  41         u8 buf[] = { 10, 0 };
  42         struct i2c_msg msg = {
  43                 .addr = priv->i2c_address,
  44                 .flags = 0,
  45                 .buf = buf,
  46                 .len = 2
  47         };
  48 
  49         dprintk("%s:\n", __func__);
  50 
  51         if (fe->ops.i2c_gate_ctrl)
  52                 fe->ops.i2c_gate_ctrl(fe, 1);
  53 
  54         ret = i2c_transfer(priv->i2c, &msg, 1);
  55         if (ret != 1)
  56                 dprintk("%s: i2c error\n", __func__);
  57 
  58         if (fe->ops.i2c_gate_ctrl)
  59                 fe->ops.i2c_gate_ctrl(fe, 0);
  60 
  61         return (ret == 1) ? 0 : ret;
  62 }
  63 
  64 static int stb6000_set_params(struct dvb_frontend *fe)
  65 {
  66         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  67         struct stb6000_priv *priv = fe->tuner_priv;
  68         unsigned int n, m;
  69         int ret;
  70         u32 freq_mhz;
  71         int bandwidth;
  72         u8 buf[12];
  73         struct i2c_msg msg = {
  74                 .addr = priv->i2c_address,
  75                 .flags = 0,
  76                 .buf = buf,
  77                 .len = 12
  78         };
  79 
  80         dprintk("%s:\n", __func__);
  81 
  82         freq_mhz = p->frequency / 1000;
  83         bandwidth = p->symbol_rate / 1000000;
  84 
  85         if (bandwidth > 31)
  86                 bandwidth = 31;
  87 
  88         if ((freq_mhz > 949) && (freq_mhz < 2151)) {
  89                 buf[0] = 0x01;
  90                 buf[1] = 0xac;
  91                 if (freq_mhz < 1950)
  92                         buf[1] = 0xaa;
  93                 if (freq_mhz < 1800)
  94                         buf[1] = 0xa8;
  95                 if (freq_mhz < 1650)
  96                         buf[1] = 0xa6;
  97                 if (freq_mhz < 1530)
  98                         buf[1] = 0xa5;
  99                 if (freq_mhz < 1470)
 100                         buf[1] = 0xa4;
 101                 if (freq_mhz < 1370)
 102                         buf[1] = 0xa2;
 103                 if (freq_mhz < 1300)
 104                         buf[1] = 0xa1;
 105                 if (freq_mhz < 1200)
 106                         buf[1] = 0xa0;
 107                 if (freq_mhz < 1075)
 108                         buf[1] = 0xbc;
 109                 if (freq_mhz < 1000)
 110                         buf[1] = 0xba;
 111                 if (freq_mhz < 1075) {
 112                         n = freq_mhz / 8; /* vco=lo*4 */
 113                         m = 2;
 114                 } else {
 115                         n = freq_mhz / 16; /* vco=lo*2 */
 116                         m = 1;
 117                 }
 118                 buf[2] = n >> 1;
 119                 buf[3] = (unsigned char)(((n & 1) << 7) |
 120                                         (m * freq_mhz - n * 16) | 0x60);
 121                 buf[4] = 0x04;
 122                 buf[5] = 0x0e;
 123 
 124                 buf[6] = (unsigned char)(bandwidth);
 125 
 126                 buf[7] = 0xd8;
 127                 buf[8] = 0xd0;
 128                 buf[9] = 0x50;
 129                 buf[10] = 0xeb;
 130                 buf[11] = 0x4f;
 131 
 132                 if (fe->ops.i2c_gate_ctrl)
 133                         fe->ops.i2c_gate_ctrl(fe, 1);
 134 
 135                 ret = i2c_transfer(priv->i2c, &msg, 1);
 136                 if (ret != 1)
 137                         dprintk("%s: i2c error\n", __func__);
 138 
 139                 udelay(10);
 140                 if (fe->ops.i2c_gate_ctrl)
 141                         fe->ops.i2c_gate_ctrl(fe, 0);
 142 
 143                 buf[0] = 0x07;
 144                 buf[1] = 0xdf;
 145                 buf[2] = 0xd0;
 146                 buf[3] = 0x50;
 147                 buf[4] = 0xfb;
 148                 msg.len = 5;
 149 
 150                 if (fe->ops.i2c_gate_ctrl)
 151                         fe->ops.i2c_gate_ctrl(fe, 1);
 152 
 153                 ret = i2c_transfer(priv->i2c, &msg, 1);
 154                 if (ret != 1)
 155                         dprintk("%s: i2c error\n", __func__);
 156 
 157                 udelay(10);
 158                 if (fe->ops.i2c_gate_ctrl)
 159                         fe->ops.i2c_gate_ctrl(fe, 0);
 160 
 161                 priv->frequency = freq_mhz * 1000;
 162 
 163                 return (ret == 1) ? 0 : ret;
 164         }
 165         return -1;
 166 }
 167 
 168 static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 169 {
 170         struct stb6000_priv *priv = fe->tuner_priv;
 171         *frequency = priv->frequency;
 172         return 0;
 173 }
 174 
 175 static const struct dvb_tuner_ops stb6000_tuner_ops = {
 176         .info = {
 177                 .name = "ST STB6000",
 178                 .frequency_min_hz =  950 * MHz,
 179                 .frequency_max_hz = 2150 * MHz
 180         },
 181         .release = stb6000_release,
 182         .sleep = stb6000_sleep,
 183         .set_params = stb6000_set_params,
 184         .get_frequency = stb6000_get_frequency,
 185 };
 186 
 187 struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
 188                                                 struct i2c_adapter *i2c)
 189 {
 190         struct stb6000_priv *priv = NULL;
 191         u8 b0[] = { 0 };
 192         u8 b1[] = { 0, 0 };
 193         struct i2c_msg msg[2] = {
 194                 {
 195                         .addr = addr,
 196                         .flags = 0,
 197                         .buf = b0,
 198                         .len = 0
 199                 }, {
 200                         .addr = addr,
 201                         .flags = I2C_M_RD,
 202                         .buf = b1,
 203                         .len = 2
 204                 }
 205         };
 206         int ret;
 207 
 208         dprintk("%s:\n", __func__);
 209 
 210         if (fe->ops.i2c_gate_ctrl)
 211                 fe->ops.i2c_gate_ctrl(fe, 1);
 212 
 213         /* is some i2c device here ? */
 214         ret = i2c_transfer(i2c, msg, 2);
 215         if (fe->ops.i2c_gate_ctrl)
 216                 fe->ops.i2c_gate_ctrl(fe, 0);
 217 
 218         if (ret != 2)
 219                 return NULL;
 220 
 221         priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
 222         if (priv == NULL)
 223                 return NULL;
 224 
 225         priv->i2c_address = addr;
 226         priv->i2c = i2c;
 227 
 228         memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
 229                                 sizeof(struct dvb_tuner_ops));
 230 
 231         fe->tuner_priv = priv;
 232 
 233         return fe;
 234 }
 235 EXPORT_SYMBOL(stb6000_attach);
 236 
 237 module_param(debug, int, 0644);
 238 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
 239 
 240 MODULE_DESCRIPTION("DVB STB6000 driver");
 241 MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
 242 MODULE_LICENSE("GPL");

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