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