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

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

DEFINITIONS

This source file includes following definitions.
  1. isl6423_write
  2. isl6423_set_modulation
  3. isl6423_voltage_boost
  4. isl6423_set_voltage
  5. isl6423_set_current
  6. isl6423_release
  7. isl6423_attach

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3         Intersil ISL6423 SEC and LNB Power supply controller
   4 
   5         Copyright (C) Manu Abraham <abraham.manu@gmail.com>
   6 
   7 */
   8 
   9 #include <linux/delay.h>
  10 #include <linux/errno.h>
  11 #include <linux/init.h>
  12 #include <linux/kernel.h>
  13 #include <linux/module.h>
  14 #include <linux/string.h>
  15 #include <linux/slab.h>
  16 
  17 #include <media/dvb_frontend.h>
  18 #include "isl6423.h"
  19 
  20 static unsigned int verbose;
  21 module_param(verbose, int, 0644);
  22 MODULE_PARM_DESC(verbose, "Set Verbosity level");
  23 
  24 #define FE_ERROR                                0
  25 #define FE_NOTICE                               1
  26 #define FE_INFO                                 2
  27 #define FE_DEBUG                                3
  28 #define FE_DEBUGREG                             4
  29 
  30 #define dprintk(__y, __z, format, arg...) do {                                          \
  31         if (__z) {                                                                      \
  32                 if      ((verbose > FE_ERROR) && (verbose > __y))                       \
  33                         printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);          \
  34                 else if ((verbose > FE_NOTICE) && (verbose > __y))                      \
  35                         printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);       \
  36                 else if ((verbose > FE_INFO) && (verbose > __y))                        \
  37                         printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);         \
  38                 else if ((verbose > FE_DEBUG) && (verbose > __y))                       \
  39                         printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);        \
  40         } else {                                                                        \
  41                 if (verbose > __y)                                                      \
  42                         printk(format, ##arg);                                          \
  43         }                                                                               \
  44 } while (0)
  45 
  46 struct isl6423_dev {
  47         const struct isl6423_config     *config;
  48         struct i2c_adapter              *i2c;
  49 
  50         u8 reg_3;
  51         u8 reg_4;
  52 
  53         unsigned int verbose;
  54 };
  55 
  56 static int isl6423_write(struct isl6423_dev *isl6423, u8 reg)
  57 {
  58         struct i2c_adapter *i2c = isl6423->i2c;
  59         u8 addr                 = isl6423->config->addr;
  60         int err = 0;
  61 
  62         struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = &reg, .len = 1 };
  63 
  64         dprintk(FE_DEBUG, 1, "write reg %02X", reg);
  65         err = i2c_transfer(i2c, &msg, 1);
  66         if (err < 0)
  67                 goto exit;
  68         return 0;
  69 
  70 exit:
  71         dprintk(FE_ERROR, 1, "I/O error <%d>", err);
  72         return err;
  73 }
  74 
  75 static int isl6423_set_modulation(struct dvb_frontend *fe)
  76 {
  77         struct isl6423_dev *isl6423             = (struct isl6423_dev *) fe->sec_priv;
  78         const struct isl6423_config *config     = isl6423->config;
  79         int err = 0;
  80         u8 reg_2 = 0;
  81 
  82         reg_2 = 0x01 << 5;
  83 
  84         if (config->mod_extern)
  85                 reg_2 |= (1 << 3);
  86         else
  87                 reg_2 |= (1 << 4);
  88 
  89         err = isl6423_write(isl6423, reg_2);
  90         if (err < 0)
  91                 goto exit;
  92         return 0;
  93 
  94 exit:
  95         dprintk(FE_ERROR, 1, "I/O error <%d>", err);
  96         return err;
  97 }
  98 
  99 static int isl6423_voltage_boost(struct dvb_frontend *fe, long arg)
 100 {
 101         struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
 102         u8 reg_3 = isl6423->reg_3;
 103         u8 reg_4 = isl6423->reg_4;
 104         int err = 0;
 105 
 106         if (arg) {
 107                 /* EN = 1, VSPEN = 1, VBOT = 1 */
 108                 reg_4 |= (1 << 4);
 109                 reg_4 |= 0x1;
 110                 reg_3 |= (1 << 3);
 111         } else {
 112                 /* EN = 1, VSPEN = 1, VBOT = 0 */
 113                 reg_4 |= (1 << 4);
 114                 reg_4 &= ~0x1;
 115                 reg_3 |= (1 << 3);
 116         }
 117         err = isl6423_write(isl6423, reg_3);
 118         if (err < 0)
 119                 goto exit;
 120 
 121         err = isl6423_write(isl6423, reg_4);
 122         if (err < 0)
 123                 goto exit;
 124 
 125         isl6423->reg_3 = reg_3;
 126         isl6423->reg_4 = reg_4;
 127 
 128         return 0;
 129 exit:
 130         dprintk(FE_ERROR, 1, "I/O error <%d>", err);
 131         return err;
 132 }
 133 
 134 
 135 static int isl6423_set_voltage(struct dvb_frontend *fe,
 136                                enum fe_sec_voltage voltage)
 137 {
 138         struct isl6423_dev *isl6423 = (struct isl6423_dev *) fe->sec_priv;
 139         u8 reg_3 = isl6423->reg_3;
 140         u8 reg_4 = isl6423->reg_4;
 141         int err = 0;
 142 
 143         switch (voltage) {
 144         case SEC_VOLTAGE_OFF:
 145                 /* EN = 0 */
 146                 reg_4 &= ~(1 << 4);
 147                 break;
 148 
 149         case SEC_VOLTAGE_13:
 150                 /* EN = 1, VSPEN = 1, VTOP = 0, VBOT = 0 */
 151                 reg_4 |= (1 << 4);
 152                 reg_4 &= ~0x3;
 153                 reg_3 |= (1 << 3);
 154                 break;
 155 
 156         case SEC_VOLTAGE_18:
 157                 /* EN = 1, VSPEN = 1, VTOP = 1, VBOT = 0 */
 158                 reg_4 |= (1 << 4);
 159                 reg_4 |=  0x2;
 160                 reg_4 &= ~0x1;
 161                 reg_3 |= (1 << 3);
 162                 break;
 163 
 164         default:
 165                 break;
 166         }
 167         err = isl6423_write(isl6423, reg_3);
 168         if (err < 0)
 169                 goto exit;
 170 
 171         err = isl6423_write(isl6423, reg_4);
 172         if (err < 0)
 173                 goto exit;
 174 
 175         isl6423->reg_3 = reg_3;
 176         isl6423->reg_4 = reg_4;
 177 
 178         return 0;
 179 exit:
 180         dprintk(FE_ERROR, 1, "I/O error <%d>", err);
 181         return err;
 182 }
 183 
 184 static int isl6423_set_current(struct dvb_frontend *fe)
 185 {
 186         struct isl6423_dev *isl6423             = (struct isl6423_dev *) fe->sec_priv;
 187         u8 reg_3 = isl6423->reg_3;
 188         const struct isl6423_config *config     = isl6423->config;
 189         int err = 0;
 190 
 191         switch (config->current_max) {
 192         case SEC_CURRENT_275m:
 193                 /* 275mA */
 194                 /* ISELH = 0, ISELL = 0 */
 195                 reg_3 &= ~0x3;
 196                 break;
 197 
 198         case SEC_CURRENT_515m:
 199                 /* 515mA */
 200                 /* ISELH = 0, ISELL = 1 */
 201                 reg_3 &= ~0x2;
 202                 reg_3 |=  0x1;
 203                 break;
 204 
 205         case SEC_CURRENT_635m:
 206                 /* 635mA */
 207                 /* ISELH = 1, ISELL = 0 */
 208                 reg_3 &= ~0x1;
 209                 reg_3 |=  0x2;
 210                 break;
 211 
 212         case SEC_CURRENT_800m:
 213                 /* 800mA */
 214                 /* ISELH = 1, ISELL = 1 */
 215                 reg_3 |= 0x3;
 216                 break;
 217         }
 218 
 219         err = isl6423_write(isl6423, reg_3);
 220         if (err < 0)
 221                 goto exit;
 222 
 223         switch (config->curlim) {
 224         case SEC_CURRENT_LIM_ON:
 225                 /* DCL = 0 */
 226                 reg_3 &= ~0x10;
 227                 break;
 228 
 229         case SEC_CURRENT_LIM_OFF:
 230                 /* DCL = 1 */
 231                 reg_3 |= 0x10;
 232                 break;
 233         }
 234 
 235         err = isl6423_write(isl6423, reg_3);
 236         if (err < 0)
 237                 goto exit;
 238 
 239         isl6423->reg_3 = reg_3;
 240 
 241         return 0;
 242 exit:
 243         dprintk(FE_ERROR, 1, "I/O error <%d>", err);
 244         return err;
 245 }
 246 
 247 static void isl6423_release(struct dvb_frontend *fe)
 248 {
 249         isl6423_set_voltage(fe, SEC_VOLTAGE_OFF);
 250 
 251         kfree(fe->sec_priv);
 252         fe->sec_priv = NULL;
 253 }
 254 
 255 struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe,
 256                                     struct i2c_adapter *i2c,
 257                                     const struct isl6423_config *config)
 258 {
 259         struct isl6423_dev *isl6423;
 260 
 261         isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL);
 262         if (!isl6423)
 263                 return NULL;
 264 
 265         isl6423->config = config;
 266         isl6423->i2c    = i2c;
 267         fe->sec_priv    = isl6423;
 268 
 269         /* SR3H = 0, SR3M = 1, SR3L = 0 */
 270         isl6423->reg_3 = 0x02 << 5;
 271         /* SR4H = 0, SR4M = 1, SR4L = 1 */
 272         isl6423->reg_4 = 0x03 << 5;
 273 
 274         if (isl6423_set_current(fe))
 275                 goto exit;
 276 
 277         if (isl6423_set_modulation(fe))
 278                 goto exit;
 279 
 280         fe->ops.release_sec             = isl6423_release;
 281         fe->ops.set_voltage             = isl6423_set_voltage;
 282         fe->ops.enable_high_lnb_voltage = isl6423_voltage_boost;
 283         isl6423->verbose                = verbose;
 284 
 285         return fe;
 286 
 287 exit:
 288         kfree(isl6423);
 289         fe->sec_priv = NULL;
 290         return NULL;
 291 }
 292 EXPORT_SYMBOL(isl6423_attach);
 293 
 294 MODULE_DESCRIPTION("ISL6423 SEC");
 295 MODULE_AUTHOR("Manu Abraham");
 296 MODULE_LICENSE("GPL");

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