root/drivers/media/pci/cx23885/cx23885-f300.c

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

DEFINITIONS

This source file includes following definitions.
  1. f300_set_line
  2. f300_get_line
  3. f300_send_byte
  4. f300_get_byte
  5. f300_xfer
  6. f300_set_voltage

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Driver for Silicon Labs C8051F300 microcontroller.
   4  *
   5  * It is used for LNB power control in TeVii S470,
   6  * TBS 6920 PCIe DVB-S2 cards.
   7  *
   8  * Microcontroller connected to cx23885 GPIO pins:
   9  * GPIO0 - data         - P0.3 F300
  10  * GPIO1 - reset        - P0.2 F300
  11  * GPIO2 - clk          - P0.1 F300
  12  * GPIO3 - busy         - P0.0 F300
  13  *
  14  * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by>
  15  */
  16 
  17 #include "cx23885.h"
  18 #include "cx23885-f300.h"
  19 
  20 #define F300_DATA       GPIO_0
  21 #define F300_RESET      GPIO_1
  22 #define F300_CLK        GPIO_2
  23 #define F300_BUSY       GPIO_3
  24 
  25 static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl)
  26 {
  27         cx23885_gpio_enable(dev, line, 1);
  28         if (lvl == 1)
  29                 cx23885_gpio_set(dev, line);
  30         else
  31                 cx23885_gpio_clear(dev, line);
  32 }
  33 
  34 static u8 f300_get_line(struct cx23885_dev *dev, u32 line)
  35 {
  36         cx23885_gpio_enable(dev, line, 0);
  37 
  38         return cx23885_gpio_get(dev, line);
  39 }
  40 
  41 static void f300_send_byte(struct cx23885_dev *dev, u8 dta)
  42 {
  43         u8 i;
  44 
  45         for (i = 0; i < 8; i++) {
  46                 f300_set_line(dev, F300_CLK, 0);
  47                 udelay(30);
  48                 f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */
  49                 udelay(30);
  50                 dta <<= 1;
  51                 f300_set_line(dev, F300_CLK, 1);
  52                 udelay(30);
  53         }
  54 }
  55 
  56 static u8 f300_get_byte(struct cx23885_dev *dev)
  57 {
  58         u8 i, dta = 0;
  59 
  60         for (i = 0; i < 8; i++) {
  61                 f300_set_line(dev, F300_CLK, 0);
  62                 udelay(30);
  63                 dta <<= 1;
  64                 f300_set_line(dev, F300_CLK, 1);
  65                 udelay(30);
  66                 dta |= f300_get_line(dev, F300_DATA);/* msb first */
  67 
  68         }
  69 
  70         return dta;
  71 }
  72 
  73 static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf)
  74 {
  75         struct cx23885_tsport *port = fe->dvb->priv;
  76         struct cx23885_dev *dev = port->dev;
  77         u8 i, temp, ret = 0;
  78 
  79         temp = buf[0];
  80         for (i = 0; i < buf[0]; i++)
  81                 temp += buf[i + 1];
  82         temp = (~temp + 1);/* get check sum */
  83         buf[1 + buf[0]] = temp;
  84 
  85         f300_set_line(dev, F300_RESET, 1);
  86         f300_set_line(dev, F300_CLK, 1);
  87         udelay(30);
  88         f300_set_line(dev, F300_DATA, 1);
  89         msleep(1);
  90 
  91         /* question: */
  92         f300_set_line(dev, F300_RESET, 0);/* begin to send data */
  93         msleep(1);
  94 
  95         f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */
  96         msleep(1);
  97 
  98         temp = buf[0];
  99         temp += 2;
 100         for (i = 0; i < temp; i++)
 101                 f300_send_byte(dev, buf[i]);
 102 
 103         f300_set_line(dev, F300_RESET, 1);/* sent data over */
 104         f300_set_line(dev, F300_DATA, 1);
 105 
 106         /* answer: */
 107         temp = 0;
 108         for (i = 0; ((i < 8) & (temp == 0)); i++) {
 109                 msleep(1);
 110                 if (f300_get_line(dev, F300_BUSY) == 0)
 111                         temp = 1;
 112         }
 113 
 114         if (i > 7) {
 115                 pr_err("%s: timeout, the slave no response\n",
 116                                                                 __func__);
 117                 ret = 1; /* timeout, the slave no response */
 118         } else { /* the slave not busy, prepare for getting data */
 119                 f300_set_line(dev, F300_RESET, 0);/*ready...*/
 120                 msleep(1);
 121                 f300_send_byte(dev, 0xe1);/* 0xe1 is Read */
 122                 msleep(1);
 123                 temp = f300_get_byte(dev);/*get the data length */
 124                 if (temp > 14)
 125                         temp = 14;
 126 
 127                 for (i = 0; i < (temp + 1); i++)
 128                         f300_get_byte(dev);/* get data to empty buffer */
 129 
 130                 f300_set_line(dev, F300_RESET, 1);/* received data over */
 131                 f300_set_line(dev, F300_DATA, 1);
 132         }
 133 
 134         return ret;
 135 }
 136 
 137 int f300_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
 138 {
 139         u8 buf[16];
 140 
 141         buf[0] = 0x05;
 142         buf[1] = 0x38;/* write port */
 143         buf[2] = 0x01;/* A port, lnb power */
 144 
 145         switch (voltage) {
 146         case SEC_VOLTAGE_13:
 147                 buf[3] = 0x01;/* power on */
 148                 buf[4] = 0x02;/* B port, H/V */
 149                 buf[5] = 0x00;/*13V v*/
 150                 break;
 151         case SEC_VOLTAGE_18:
 152                 buf[3] = 0x01;
 153                 buf[4] = 0x02;
 154                 buf[5] = 0x01;/* 18V h*/
 155                 break;
 156         case SEC_VOLTAGE_OFF:
 157                 buf[3] = 0x00;/* power off */
 158                 buf[4] = 0x00;
 159                 buf[5] = 0x00;
 160                 break;
 161         }
 162 
 163         return f300_xfer(fe, buf);
 164 }

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