1c0adca734013389ac81513da546947e75d95151aAntti Palosaari/* 2c0adca734013389ac81513da546947e75d95151aAntti Palosaari * Realtek RTL2830 DVB-T demodulator driver 3c0adca734013389ac81513da546947e75d95151aAntti Palosaari * 4c0adca734013389ac81513da546947e75d95151aAntti Palosaari * Copyright (C) 2011 Antti Palosaari <crope@iki.fi> 5c0adca734013389ac81513da546947e75d95151aAntti Palosaari * 6c0adca734013389ac81513da546947e75d95151aAntti Palosaari * This program is free software; you can redistribute it and/or modify 7c0adca734013389ac81513da546947e75d95151aAntti Palosaari * it under the terms of the GNU General Public License as published by 8c0adca734013389ac81513da546947e75d95151aAntti Palosaari * the Free Software Foundation; either version 2 of the License, or 9c0adca734013389ac81513da546947e75d95151aAntti Palosaari * (at your option) any later version. 10c0adca734013389ac81513da546947e75d95151aAntti Palosaari * 11c0adca734013389ac81513da546947e75d95151aAntti Palosaari * This program is distributed in the hope that it will be useful, 12c0adca734013389ac81513da546947e75d95151aAntti Palosaari * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c0adca734013389ac81513da546947e75d95151aAntti Palosaari * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14c0adca734013389ac81513da546947e75d95151aAntti Palosaari * GNU General Public License for more details. 15c0adca734013389ac81513da546947e75d95151aAntti Palosaari * 16c0adca734013389ac81513da546947e75d95151aAntti Palosaari * You should have received a copy of the GNU General Public License along 17c0adca734013389ac81513da546947e75d95151aAntti Palosaari * with this program; if not, write to the Free Software Foundation, Inc., 18c0adca734013389ac81513da546947e75d95151aAntti Palosaari * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19c0adca734013389ac81513da546947e75d95151aAntti Palosaari */ 20c0adca734013389ac81513da546947e75d95151aAntti Palosaari 21c0adca734013389ac81513da546947e75d95151aAntti Palosaari 22c0adca734013389ac81513da546947e75d95151aAntti Palosaari/* 23c0adca734013389ac81513da546947e75d95151aAntti Palosaari * Driver implements own I2C-adapter for tuner I2C access. That's since chip 24c0adca734013389ac81513da546947e75d95151aAntti Palosaari * have unusual I2C-gate control which closes gate automatically after each 25c0adca734013389ac81513da546947e75d95151aAntti Palosaari * I2C transfer. Using own I2C adapter we can workaround that. 26c0adca734013389ac81513da546947e75d95151aAntti Palosaari */ 27c0adca734013389ac81513da546947e75d95151aAntti Palosaari 28c0adca734013389ac81513da546947e75d95151aAntti Palosaari#include "rtl2830_priv.h" 29c0adca734013389ac81513da546947e75d95151aAntti Palosaari 3037ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab/* Max transfer size done by I2C transfer functions */ 3137ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab#define MAX_XFER_SIZE 64 3237ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab 330485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari/* write multiple hardware registers */ 343a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaaristatic int rtl2830_wr(struct rtl2830_priv *priv, u8 reg, const u8 *val, int len) 35c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 36c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret; 3737ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab u8 buf[MAX_XFER_SIZE]; 38c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct i2c_msg msg[1] = { 39c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 40c0adca734013389ac81513da546947e75d95151aAntti Palosaari .addr = priv->cfg.i2c_addr, 41c0adca734013389ac81513da546947e75d95151aAntti Palosaari .flags = 0, 4237ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab .len = 1 + len, 43c0adca734013389ac81513da546947e75d95151aAntti Palosaari .buf = buf, 44c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 45c0adca734013389ac81513da546947e75d95151aAntti Palosaari }; 46c0adca734013389ac81513da546947e75d95151aAntti Palosaari 4737ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab if (1 + len > sizeof(buf)) { 4837ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab dev_warn(&priv->i2c->dev, 4937ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab "%s: i2c wr reg=%04x: len=%d is too big!\n", 5037ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab KBUILD_MODNAME, reg, len); 5137ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab return -EINVAL; 5237ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab } 5337ebaf6891ee81687bb558e8375c0712d8264ed8Mauro Carvalho Chehab 540485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari buf[0] = reg; 550485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari memcpy(&buf[1], val, len); 56c0adca734013389ac81513da546947e75d95151aAntti Palosaari 57c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = i2c_transfer(priv->i2c, msg, 1); 58c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret == 1) { 59c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = 0; 60c0adca734013389ac81513da546947e75d95151aAntti Palosaari } else { 6186ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \ 6286ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari "len=%d\n", KBUILD_MODNAME, ret, reg, len); 63c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = -EREMOTEIO; 64c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 65c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 66c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 67c0adca734013389ac81513da546947e75d95151aAntti Palosaari 680485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari/* read multiple hardware registers */ 690485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaaristatic int rtl2830_rd(struct rtl2830_priv *priv, u8 reg, u8 *val, int len) 70c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 71c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret; 72c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct i2c_msg msg[2] = { 73c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 74c0adca734013389ac81513da546947e75d95151aAntti Palosaari .addr = priv->cfg.i2c_addr, 75c0adca734013389ac81513da546947e75d95151aAntti Palosaari .flags = 0, 760485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari .len = 1, 770485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari .buf = ®, 78c0adca734013389ac81513da546947e75d95151aAntti Palosaari }, { 79c0adca734013389ac81513da546947e75d95151aAntti Palosaari .addr = priv->cfg.i2c_addr, 80c0adca734013389ac81513da546947e75d95151aAntti Palosaari .flags = I2C_M_RD, 81c0adca734013389ac81513da546947e75d95151aAntti Palosaari .len = len, 82c0adca734013389ac81513da546947e75d95151aAntti Palosaari .buf = val, 83c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 84c0adca734013389ac81513da546947e75d95151aAntti Palosaari }; 85c0adca734013389ac81513da546947e75d95151aAntti Palosaari 86c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = i2c_transfer(priv->i2c, msg, 2); 87c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret == 2) { 88c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = 0; 89c0adca734013389ac81513da546947e75d95151aAntti Palosaari } else { 9086ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \ 9186ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari "len=%d\n", KBUILD_MODNAME, ret, reg, len); 92c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = -EREMOTEIO; 93c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 94c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 95c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 96c0adca734013389ac81513da546947e75d95151aAntti Palosaari 970485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari/* write multiple registers */ 983a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaaristatic int rtl2830_wr_regs(struct rtl2830_priv *priv, u16 reg, const u8 *val, 993a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaari int len) 1000485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari{ 1010485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari int ret; 1020485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari u8 reg2 = (reg >> 0) & 0xff; 1030485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari u8 page = (reg >> 8) & 0xff; 1040485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1050485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari /* switch bank if needed */ 1060485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari if (page != priv->page) { 1070485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari ret = rtl2830_wr(priv, 0x00, &page, 1); 1080485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari if (ret) 1090485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari return ret; 1100485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1110485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari priv->page = page; 1120485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari } 1130485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1140485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari return rtl2830_wr(priv, reg2, val, len); 1150485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari} 1160485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1170485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari/* read multiple registers */ 1180485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaaristatic int rtl2830_rd_regs(struct rtl2830_priv *priv, u16 reg, u8 *val, int len) 1190485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari{ 1200485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari int ret; 1210485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari u8 reg2 = (reg >> 0) & 0xff; 1220485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari u8 page = (reg >> 8) & 0xff; 1230485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1240485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari /* switch bank if needed */ 1250485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari if (page != priv->page) { 1260485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari ret = rtl2830_wr(priv, 0x00, &page, 1); 1270485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari if (ret) 1280485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari return ret; 1290485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1300485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari priv->page = page; 1310485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari } 1320485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 1330485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari return rtl2830_rd(priv, reg2, val, len); 1340485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari} 1350485a7089b8d6c11fe2db1123a1ed39a2676592fAntti Palosaari 136c0adca734013389ac81513da546947e75d95151aAntti Palosaari/* read single register */ 137c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_rd_reg(struct rtl2830_priv *priv, u16 reg, u8 *val) 138c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 139c0adca734013389ac81513da546947e75d95151aAntti Palosaari return rtl2830_rd_regs(priv, reg, val, 1); 140c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 141c0adca734013389ac81513da546947e75d95151aAntti Palosaari 142c0adca734013389ac81513da546947e75d95151aAntti Palosaari/* write single register with mask */ 143a17ff2eed6812eff319a4a74854db55298319bbeMauro Carvalho Chehabstatic int rtl2830_wr_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 val, u8 mask) 144c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 145c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret; 146c0adca734013389ac81513da546947e75d95151aAntti Palosaari u8 tmp; 147c0adca734013389ac81513da546947e75d95151aAntti Palosaari 148c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* no need for read if whole reg is written */ 149c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (mask != 0xff) { 150c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_rd_regs(priv, reg, &tmp, 1); 151c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 152c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 153c0adca734013389ac81513da546947e75d95151aAntti Palosaari 154c0adca734013389ac81513da546947e75d95151aAntti Palosaari val &= mask; 155c0adca734013389ac81513da546947e75d95151aAntti Palosaari tmp &= ~mask; 156c0adca734013389ac81513da546947e75d95151aAntti Palosaari val |= tmp; 157c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 158c0adca734013389ac81513da546947e75d95151aAntti Palosaari 159c0adca734013389ac81513da546947e75d95151aAntti Palosaari return rtl2830_wr_regs(priv, reg, &val, 1); 160c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 161c0adca734013389ac81513da546947e75d95151aAntti Palosaari 162c0adca734013389ac81513da546947e75d95151aAntti Palosaari/* read single register with mask */ 163a17ff2eed6812eff319a4a74854db55298319bbeMauro Carvalho Chehabstatic int rtl2830_rd_reg_mask(struct rtl2830_priv *priv, u16 reg, u8 *val, u8 mask) 164c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 165c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret, i; 166c0adca734013389ac81513da546947e75d95151aAntti Palosaari u8 tmp; 167c0adca734013389ac81513da546947e75d95151aAntti Palosaari 168c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_rd_regs(priv, reg, &tmp, 1); 169c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 170c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 171c0adca734013389ac81513da546947e75d95151aAntti Palosaari 172c0adca734013389ac81513da546947e75d95151aAntti Palosaari tmp &= mask; 173c0adca734013389ac81513da546947e75d95151aAntti Palosaari 174c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* find position of the first bit */ 175c0adca734013389ac81513da546947e75d95151aAntti Palosaari for (i = 0; i < 8; i++) { 176c0adca734013389ac81513da546947e75d95151aAntti Palosaari if ((mask >> i) & 0x01) 177c0adca734013389ac81513da546947e75d95151aAntti Palosaari break; 178c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 179c0adca734013389ac81513da546947e75d95151aAntti Palosaari *val = tmp >> i; 180c0adca734013389ac81513da546947e75d95151aAntti Palosaari 181c0adca734013389ac81513da546947e75d95151aAntti Palosaari return 0; 182c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 183c0adca734013389ac81513da546947e75d95151aAntti Palosaari 184c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_init(struct dvb_frontend *fe) 185c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 186c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 187c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret, i; 188c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_reg_val_mask tab[] = { 189c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x00d, 0x01, 0x03 }, 190c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x00d, 0x10, 0x10 }, 191c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x104, 0x00, 0x1e }, 192c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x105, 0x80, 0x80 }, 193c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x110, 0x02, 0x03 }, 194c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x110, 0x08, 0x0c }, 195c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x17b, 0x00, 0x40 }, 196c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x17d, 0x05, 0x0f }, 197c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x17d, 0x50, 0xf0 }, 198c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x18c, 0x08, 0x0f }, 199c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x18d, 0x00, 0xc0 }, 200c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x188, 0x05, 0x0f }, 201c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x189, 0x00, 0xfc }, 202c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x2d5, 0x02, 0x02 }, 203c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x2f1, 0x02, 0x06 }, 204c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x2f1, 0x20, 0xf8 }, 205c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x16d, 0x00, 0x01 }, 206c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x1a6, 0x00, 0x80 }, 207c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x106, priv->cfg.vtop, 0x3f }, 208c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x107, priv->cfg.krf, 0x3f }, 209c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x112, 0x28, 0xff }, 210c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x103, priv->cfg.agc_targ_val, 0xff }, 211c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x00a, 0x02, 0x07 }, 212c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x140, 0x0c, 0x3c }, 213c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x140, 0x40, 0xc0 }, 214c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x15b, 0x05, 0x07 }, 215c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x15b, 0x28, 0x38 }, 216c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x15c, 0x05, 0x07 }, 217c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x15c, 0x28, 0x38 }, 218c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x115, priv->cfg.spec_inv, 0x01 }, 219c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x16f, 0x01, 0x07 }, 220c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x170, 0x18, 0x38 }, 221c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x172, 0x0f, 0x0f }, 222c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x173, 0x08, 0x38 }, 223c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x175, 0x01, 0x07 }, 224c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 0x176, 0x00, 0xc0 }, 225c0adca734013389ac81513da546947e75d95151aAntti Palosaari }; 226c0adca734013389ac81513da546947e75d95151aAntti Palosaari 227c0adca734013389ac81513da546947e75d95151aAntti Palosaari for (i = 0; i < ARRAY_SIZE(tab); i++) { 228c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_reg_mask(priv, tab[i].reg, tab[i].val, 229c0adca734013389ac81513da546947e75d95151aAntti Palosaari tab[i].mask); 230c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 231c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 232c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 233c0adca734013389ac81513da546947e75d95151aAntti Palosaari 234c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_regs(priv, 0x18f, "\x28\x00", 2); 235c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 236c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 237c0adca734013389ac81513da546947e75d95151aAntti Palosaari 238c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_regs(priv, 0x195, 239c0adca734013389ac81513da546947e75d95151aAntti Palosaari "\x04\x06\x0a\x12\x0a\x12\x1e\x28", 8); 240c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 241c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 242c0adca734013389ac81513da546947e75d95151aAntti Palosaari 243c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* TODO: spec init */ 244c0adca734013389ac81513da546947e75d95151aAntti Palosaari 245c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* soft reset */ 246c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_reg_mask(priv, 0x101, 0x04, 0x04); 247c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 248c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 249c0adca734013389ac81513da546947e75d95151aAntti Palosaari 250c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_reg_mask(priv, 0x101, 0x00, 0x04); 251c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 252c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 253c0adca734013389ac81513da546947e75d95151aAntti Palosaari 254a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari priv->sleeping = false; 255a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari 256c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 257c0adca734013389ac81513da546947e75d95151aAntti Palosaarierr: 25886ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 259c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 260c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 261c0adca734013389ac81513da546947e75d95151aAntti Palosaari 262a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaaristatic int rtl2830_sleep(struct dvb_frontend *fe) 263a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari{ 264a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 265a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari priv->sleeping = true; 266a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari return 0; 267a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari} 268a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari 269a17ff2eed6812eff319a4a74854db55298319bbeMauro Carvalho Chehabstatic int rtl2830_get_tune_settings(struct dvb_frontend *fe, 270c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct dvb_frontend_tune_settings *s) 271c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 272c0adca734013389ac81513da546947e75d95151aAntti Palosaari s->min_delay_ms = 500; 273c0adca734013389ac81513da546947e75d95151aAntti Palosaari s->step_size = fe->ops.info.frequency_stepsize * 2; 274c0adca734013389ac81513da546947e75d95151aAntti Palosaari s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; 275c0adca734013389ac81513da546947e75d95151aAntti Palosaari 276c0adca734013389ac81513da546947e75d95151aAntti Palosaari return 0; 277c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 278c0adca734013389ac81513da546947e75d95151aAntti Palosaari 279c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_set_frontend(struct dvb_frontend *fe) 280c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 281c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 282c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct dtv_frontend_properties *c = &fe->dtv_property_cache; 283c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret, i; 28466b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari u64 num; 28566b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari u8 buf[3], tmp; 28666b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari u32 if_ctl, if_frequency; 2873a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaari static const u8 bw_params1[3][34] = { 288c0adca734013389ac81513da546947e75d95151aAntti Palosaari { 289c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x1f, 0xf0, 0x1f, 0xf0, 0x1f, 0xfa, 0x00, 0x17, 0x00, 0x41, 290c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x00, 0x64, 0x00, 0x67, 0x00, 0x38, 0x1f, 0xde, 0x1f, 0x7a, 291c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x1f, 0x47, 0x1f, 0x7c, 0x00, 0x30, 0x01, 0x4b, 0x02, 0x82, 292c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x03, 0x73, 0x03, 0xcf, /* 6 MHz */ 293c0adca734013389ac81513da546947e75d95151aAntti Palosaari }, { 294c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x1f, 0xfa, 0x1f, 0xda, 0x1f, 0xc1, 0x1f, 0xb3, 0x1f, 0xca, 295c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x00, 0x07, 0x00, 0x4d, 0x00, 0x6d, 0x00, 0x40, 0x1f, 0xca, 296c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x1f, 0x4d, 0x1f, 0x2a, 0x1f, 0xb2, 0x00, 0xec, 0x02, 0x7e, 297c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x03, 0xd0, 0x04, 0x53, /* 7 MHz */ 298c0adca734013389ac81513da546947e75d95151aAntti Palosaari }, { 299c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x00, 0x10, 0x00, 0x0e, 0x1f, 0xf7, 0x1f, 0xc9, 0x1f, 0xa0, 300c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x1f, 0xa6, 0x1f, 0xec, 0x00, 0x4e, 0x00, 0x7d, 0x00, 0x3a, 301c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x1f, 0x98, 0x1f, 0x10, 0x1f, 0x40, 0x00, 0x75, 0x02, 0x5f, 302c0adca734013389ac81513da546947e75d95151aAntti Palosaari 0x04, 0x24, 0x04, 0xdb, /* 8 MHz */ 303c0adca734013389ac81513da546947e75d95151aAntti Palosaari }, 304c0adca734013389ac81513da546947e75d95151aAntti Palosaari }; 3053a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaari static const u8 bw_params2[3][6] = { 3063a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaari {0xc3, 0x0c, 0x44, 0x33, 0x33, 0x30}, /* 6 MHz */ 3073a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaari {0xb8, 0xe3, 0x93, 0x99, 0x99, 0x98}, /* 7 MHz */ 3083a2fca2684bd8730a270197d231d8d023d759d3fAntti Palosaari {0xae, 0xba, 0xf3, 0x26, 0x66, 0x64}, /* 8 MHz */ 309c0adca734013389ac81513da546947e75d95151aAntti Palosaari }; 310c0adca734013389ac81513da546947e75d95151aAntti Palosaari 31186ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, 31286ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari "%s: frequency=%d bandwidth_hz=%d inversion=%d\n", 31386ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari __func__, c->frequency, c->bandwidth_hz, c->inversion); 314c0adca734013389ac81513da546947e75d95151aAntti Palosaari 315c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* program tuner */ 316c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (fe->ops.tuner_ops.set_params) 317c0adca734013389ac81513da546947e75d95151aAntti Palosaari fe->ops.tuner_ops.set_params(fe); 318c0adca734013389ac81513da546947e75d95151aAntti Palosaari 319c0adca734013389ac81513da546947e75d95151aAntti Palosaari switch (c->bandwidth_hz) { 320c0adca734013389ac81513da546947e75d95151aAntti Palosaari case 6000000: 321c0adca734013389ac81513da546947e75d95151aAntti Palosaari i = 0; 322c0adca734013389ac81513da546947e75d95151aAntti Palosaari break; 323c0adca734013389ac81513da546947e75d95151aAntti Palosaari case 7000000: 324c0adca734013389ac81513da546947e75d95151aAntti Palosaari i = 1; 325c0adca734013389ac81513da546947e75d95151aAntti Palosaari break; 326c0adca734013389ac81513da546947e75d95151aAntti Palosaari case 8000000: 327c0adca734013389ac81513da546947e75d95151aAntti Palosaari i = 2; 328c0adca734013389ac81513da546947e75d95151aAntti Palosaari break; 329c0adca734013389ac81513da546947e75d95151aAntti Palosaari default: 33086ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: invalid bandwidth\n", __func__); 331c0adca734013389ac81513da546947e75d95151aAntti Palosaari return -EINVAL; 332c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 333c0adca734013389ac81513da546947e75d95151aAntti Palosaari 334c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_reg_mask(priv, 0x008, i << 1, 0x06); 335c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 336c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 337c0adca734013389ac81513da546947e75d95151aAntti Palosaari 33866b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari /* program if frequency */ 33966b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari if (fe->ops.tuner_ops.get_if_frequency) 34066b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency); 34166b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari else 34266b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari ret = -EINVAL; 34366b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari 34466b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari if (ret < 0) 34566b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari goto err; 34666b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari 34766b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari num = if_frequency % priv->cfg.xtal; 34866b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari num *= 0x400000; 34966b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari num = div_u64(num, priv->cfg.xtal); 35066b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari num = -num; 35166b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari if_ctl = num & 0x3fffff; 35266b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d if_ctl=%08x\n", 35366b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari __func__, if_frequency, if_ctl); 35466b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari 35566b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari ret = rtl2830_rd_reg_mask(priv, 0x119, &tmp, 0xc0); /* b[7:6] */ 35666b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari if (ret) 35766b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari goto err; 35866b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari 35966b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari buf[0] = tmp << 6; 36066b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari buf[0] |= (if_ctl >> 16) & 0x3f; 36166b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari buf[1] = (if_ctl >> 8) & 0xff; 36266b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari buf[2] = (if_ctl >> 0) & 0xff; 36366b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari 36466b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari ret = rtl2830_wr_regs(priv, 0x119, buf, 3); 36566b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari if (ret) 36666b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari goto err; 36766b3c4deb9735e18d5b71dbcbf9532bdf080d001Antti Palosaari 368c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* 1/2 split I2C write */ 369c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_regs(priv, 0x11c, &bw_params1[i][0], 17); 370c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 371c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 372c0adca734013389ac81513da546947e75d95151aAntti Palosaari 373c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* 2/2 split I2C write */ 374c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_regs(priv, 0x12d, &bw_params1[i][17], 17); 375c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 376c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 377c0adca734013389ac81513da546947e75d95151aAntti Palosaari 378c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_regs(priv, 0x19d, bw_params2[i], 6); 379c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 380c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 381c0adca734013389ac81513da546947e75d95151aAntti Palosaari 382c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 383c0adca734013389ac81513da546947e75d95151aAntti Palosaarierr: 38486ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 385c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 386c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 387c0adca734013389ac81513da546947e75d95151aAntti Palosaari 388631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaaristatic int rtl2830_get_frontend(struct dvb_frontend *fe) 389631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari{ 390631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 391631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari struct dtv_frontend_properties *c = &fe->dtv_property_cache; 392631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari int ret; 393631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari u8 buf[3]; 394631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 395c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari if (priv->sleeping) 396c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari return 0; 397c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari 398631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari ret = rtl2830_rd_regs(priv, 0x33c, buf, 2); 399631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari if (ret) 400631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari goto err; 401631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 402631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari ret = rtl2830_rd_reg(priv, 0x351, &buf[2]); 403631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari if (ret) 404631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari goto err; 405631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 40686ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: TPS=%*ph\n", __func__, 3, buf); 407631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 408631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari switch ((buf[0] >> 2) & 3) { 409631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 0: 410631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->modulation = QPSK; 411631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 412631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 1: 413631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->modulation = QAM_16; 414631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 415631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 2: 416631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->modulation = QAM_64; 417631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 418631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari } 419631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 420631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari switch ((buf[2] >> 2) & 1) { 421631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 0: 422631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->transmission_mode = TRANSMISSION_MODE_2K; 423631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 424631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 1: 425631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->transmission_mode = TRANSMISSION_MODE_8K; 426631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari } 427631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 428631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari switch ((buf[2] >> 0) & 3) { 429631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 0: 430631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->guard_interval = GUARD_INTERVAL_1_32; 431631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 432631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 1: 433631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->guard_interval = GUARD_INTERVAL_1_16; 434631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 435631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 2: 436631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->guard_interval = GUARD_INTERVAL_1_8; 437631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 438631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 3: 439631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->guard_interval = GUARD_INTERVAL_1_4; 440631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 441631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari } 442631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 443631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari switch ((buf[0] >> 4) & 7) { 444631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 0: 445631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->hierarchy = HIERARCHY_NONE; 446631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 447631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 1: 448631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->hierarchy = HIERARCHY_1; 449631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 450631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 2: 451631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->hierarchy = HIERARCHY_2; 452631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 453631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 3: 454631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->hierarchy = HIERARCHY_4; 455631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 456631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari } 457631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 458631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari switch ((buf[1] >> 3) & 7) { 459631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 0: 460631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_HP = FEC_1_2; 461631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 462631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 1: 463631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_HP = FEC_2_3; 464631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 465631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 2: 466631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_HP = FEC_3_4; 467631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 468631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 3: 469631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_HP = FEC_5_6; 470631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 471631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 4: 472631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_HP = FEC_7_8; 473631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 474631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari } 475631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 476631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari switch ((buf[1] >> 0) & 7) { 477631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 0: 478631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_LP = FEC_1_2; 479631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 480631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 1: 481631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_LP = FEC_2_3; 482631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 483631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 2: 484631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_LP = FEC_3_4; 485631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 486631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 3: 487631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_LP = FEC_5_6; 488631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 489631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari case 4: 490631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari c->code_rate_LP = FEC_7_8; 491631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari break; 492631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari } 493631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 494631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari return 0; 495631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaarierr: 49686ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 497631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari return ret; 498631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari} 499631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari 500c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_read_status(struct dvb_frontend *fe, fe_status_t *status) 501c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 502c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 503c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret; 504c0adca734013389ac81513da546947e75d95151aAntti Palosaari u8 tmp; 505c0adca734013389ac81513da546947e75d95151aAntti Palosaari *status = 0; 506c0adca734013389ac81513da546947e75d95151aAntti Palosaari 507a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari if (priv->sleeping) 508a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari return 0; 509a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari 510c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_rd_reg_mask(priv, 0x351, &tmp, 0x78); /* [6:3] */ 511c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 512c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 513c0adca734013389ac81513da546947e75d95151aAntti Palosaari 514c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (tmp == 11) { 515c0adca734013389ac81513da546947e75d95151aAntti Palosaari *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 516c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; 517c0adca734013389ac81513da546947e75d95151aAntti Palosaari } else if (tmp == 10) { 518c0adca734013389ac81513da546947e75d95151aAntti Palosaari *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | 519c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_HAS_VITERBI; 520c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 521c0adca734013389ac81513da546947e75d95151aAntti Palosaari 522c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 523c0adca734013389ac81513da546947e75d95151aAntti Palosaarierr: 52486ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 525c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 526c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 527c0adca734013389ac81513da546947e75d95151aAntti Palosaari 528c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_read_snr(struct dvb_frontend *fe, u16 *snr) 529c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 530eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 531eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari int ret, hierarchy, constellation; 532eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari u8 buf[2], tmp; 533eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari u16 tmp16; 534eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari#define CONSTELLATION_NUM 3 535eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari#define HIERARCHY_NUM 4 536eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari static const u32 snr_constant[CONSTELLATION_NUM][HIERARCHY_NUM] = { 537eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari { 70705899, 70705899, 70705899, 70705899 }, 538eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari { 82433173, 82433173, 87483115, 94445660 }, 539eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari { 92888734, 92888734, 95487525, 99770748 }, 540eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari }; 541eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 542c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari if (priv->sleeping) 543c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari return 0; 544c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari 545eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari /* reports SNR in resolution of 0.1 dB */ 546eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 547eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari ret = rtl2830_rd_reg(priv, 0x33c, &tmp); 548eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari if (ret) 549eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari goto err; 550eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 551eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari constellation = (tmp >> 2) & 0x03; /* [3:2] */ 552eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari if (constellation > CONSTELLATION_NUM - 1) 553eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari goto err; 554eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 555eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari hierarchy = (tmp >> 4) & 0x07; /* [6:4] */ 556eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari if (hierarchy > HIERARCHY_NUM - 1) 557eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari goto err; 558eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 559eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari ret = rtl2830_rd_regs(priv, 0x40c, buf, 2); 560eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari if (ret) 561eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari goto err; 562eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 563eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari tmp16 = buf[0] << 8 | buf[1]; 564eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 565eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari if (tmp16) 566eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari *snr = (snr_constant[constellation][hierarchy] - 567eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari intlog10(tmp16)) / ((1 << 24) / 100); 568eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari else 569eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari *snr = 0; 570eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari 571c0adca734013389ac81513da546947e75d95151aAntti Palosaari return 0; 572eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaarierr: 57386ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 574eba672a045d8fbf62b229eac74ef444b6000c4c2Antti Palosaari return ret; 575c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 576c0adca734013389ac81513da546947e75d95151aAntti Palosaari 577c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_read_ber(struct dvb_frontend *fe, u32 *ber) 578c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 579525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 580525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari int ret; 581525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari u8 buf[2]; 582525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari 583c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari if (priv->sleeping) 584c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari return 0; 585c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari 586525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari ret = rtl2830_rd_regs(priv, 0x34e, buf, 2); 587525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari if (ret) 588525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari goto err; 589525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari 590525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari *ber = buf[0] << 8 | buf[1]; 591525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari 592c0adca734013389ac81513da546947e75d95151aAntti Palosaari return 0; 593525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaarierr: 59486ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 595525ffc19b992f5d6a25413c36ba543a82585ed89Antti Palosaari return ret; 596c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 597c0adca734013389ac81513da546947e75d95151aAntti Palosaari 598c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 599c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 600c0adca734013389ac81513da546947e75d95151aAntti Palosaari *ucblocks = 0; 601c0adca734013389ac81513da546947e75d95151aAntti Palosaari return 0; 602c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 603c0adca734013389ac81513da546947e75d95151aAntti Palosaari 604c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 605c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 60678e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 60778e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari int ret; 60878e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari u8 buf[2]; 60978e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari u16 if_agc_raw, if_agc; 61078e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari 611c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari if (priv->sleeping) 612c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari return 0; 613c188637dc5a25aec6a21279524405c8fe96f2f4bAntti Palosaari 61478e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari ret = rtl2830_rd_regs(priv, 0x359, buf, 2); 61578e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari if (ret) 61678e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari goto err; 61778e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari 61878e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari if_agc_raw = (buf[0] << 8 | buf[1]) & 0x3fff; 61978e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari 62078e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari if (if_agc_raw & (1 << 9)) 62178e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari if_agc = -(~(if_agc_raw - 1) & 0x1ff); 62278e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari else 62378e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari if_agc = if_agc_raw; 62478e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari 62578e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari *strength = (u8) (55 - if_agc / 182); 62678e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari *strength |= *strength << 8; 62778e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari 628c0adca734013389ac81513da546947e75d95151aAntti Palosaari return 0; 62978e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaarierr: 63086ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 63178e750754bf0cc86d36149536bc7f3382710a2eeAntti Palosaari return ret; 632c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 633c0adca734013389ac81513da546947e75d95151aAntti Palosaari 634c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic struct dvb_frontend_ops rtl2830_ops; 635c0adca734013389ac81513da546947e75d95151aAntti Palosaari 636c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic u32 rtl2830_tuner_i2c_func(struct i2c_adapter *adapter) 637c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 638c0adca734013389ac81513da546947e75d95151aAntti Palosaari return I2C_FUNC_I2C; 639c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 640c0adca734013389ac81513da546947e75d95151aAntti Palosaari 641c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic int rtl2830_tuner_i2c_xfer(struct i2c_adapter *i2c_adap, 642c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct i2c_msg msg[], int num) 643c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 644c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = i2c_get_adapdata(i2c_adap); 645c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret; 646c0adca734013389ac81513da546947e75d95151aAntti Palosaari 647c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* open i2c-gate */ 648c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_wr_reg_mask(priv, 0x101, 0x08, 0x08); 649c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 650c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 651c0adca734013389ac81513da546947e75d95151aAntti Palosaari 652c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = i2c_transfer(priv->i2c, msg, num); 653c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret < 0) 65486ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_warn(&priv->i2c->dev, "%s: tuner i2c failed=%d\n", 65586ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari KBUILD_MODNAME, ret); 656c0adca734013389ac81513da546947e75d95151aAntti Palosaari 657c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 658c0adca734013389ac81513da546947e75d95151aAntti Palosaarierr: 65986ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 660c0adca734013389ac81513da546947e75d95151aAntti Palosaari return ret; 661c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 662c0adca734013389ac81513da546947e75d95151aAntti Palosaari 663c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic struct i2c_algorithm rtl2830_tuner_i2c_algo = { 664c0adca734013389ac81513da546947e75d95151aAntti Palosaari .master_xfer = rtl2830_tuner_i2c_xfer, 665c0adca734013389ac81513da546947e75d95151aAntti Palosaari .functionality = rtl2830_tuner_i2c_func, 666c0adca734013389ac81513da546947e75d95151aAntti Palosaari}; 667c0adca734013389ac81513da546947e75d95151aAntti Palosaari 668c0adca734013389ac81513da546947e75d95151aAntti Palosaaristruct i2c_adapter *rtl2830_get_tuner_i2c_adapter(struct dvb_frontend *fe) 669c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 670c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 671c0adca734013389ac81513da546947e75d95151aAntti Palosaari return &priv->tuner_i2c_adapter; 672c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 673c0adca734013389ac81513da546947e75d95151aAntti PalosaariEXPORT_SYMBOL(rtl2830_get_tuner_i2c_adapter); 674c0adca734013389ac81513da546947e75d95151aAntti Palosaari 675c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic void rtl2830_release(struct dvb_frontend *fe) 676c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 677c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = fe->demodulator_priv; 678c0adca734013389ac81513da546947e75d95151aAntti Palosaari 679c0adca734013389ac81513da546947e75d95151aAntti Palosaari i2c_del_adapter(&priv->tuner_i2c_adapter); 680c0adca734013389ac81513da546947e75d95151aAntti Palosaari kfree(priv); 681c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 682c0adca734013389ac81513da546947e75d95151aAntti Palosaari 683c0adca734013389ac81513da546947e75d95151aAntti Palosaaristruct dvb_frontend *rtl2830_attach(const struct rtl2830_config *cfg, 684c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct i2c_adapter *i2c) 685c0adca734013389ac81513da546947e75d95151aAntti Palosaari{ 686c0adca734013389ac81513da546947e75d95151aAntti Palosaari struct rtl2830_priv *priv = NULL; 687c0adca734013389ac81513da546947e75d95151aAntti Palosaari int ret = 0; 688c0adca734013389ac81513da546947e75d95151aAntti Palosaari u8 tmp; 689c0adca734013389ac81513da546947e75d95151aAntti Palosaari 690c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* allocate memory for the internal state */ 691c0adca734013389ac81513da546947e75d95151aAntti Palosaari priv = kzalloc(sizeof(struct rtl2830_priv), GFP_KERNEL); 692c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (priv == NULL) 693c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 694c0adca734013389ac81513da546947e75d95151aAntti Palosaari 695c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* setup the priv */ 696c0adca734013389ac81513da546947e75d95151aAntti Palosaari priv->i2c = i2c; 697c0adca734013389ac81513da546947e75d95151aAntti Palosaari memcpy(&priv->cfg, cfg, sizeof(struct rtl2830_config)); 698c0adca734013389ac81513da546947e75d95151aAntti Palosaari 699c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* check if the demod is there */ 700c0adca734013389ac81513da546947e75d95151aAntti Palosaari ret = rtl2830_rd_reg(priv, 0x000, &tmp); 701c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (ret) 702c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 703c0adca734013389ac81513da546947e75d95151aAntti Palosaari 704c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* create dvb_frontend */ 705c0adca734013389ac81513da546947e75d95151aAntti Palosaari memcpy(&priv->fe.ops, &rtl2830_ops, sizeof(struct dvb_frontend_ops)); 706c0adca734013389ac81513da546947e75d95151aAntti Palosaari priv->fe.demodulator_priv = priv; 707c0adca734013389ac81513da546947e75d95151aAntti Palosaari 708c0adca734013389ac81513da546947e75d95151aAntti Palosaari /* create tuner i2c adapter */ 709c0adca734013389ac81513da546947e75d95151aAntti Palosaari strlcpy(priv->tuner_i2c_adapter.name, "RTL2830 tuner I2C adapter", 710c0adca734013389ac81513da546947e75d95151aAntti Palosaari sizeof(priv->tuner_i2c_adapter.name)); 711c0adca734013389ac81513da546947e75d95151aAntti Palosaari priv->tuner_i2c_adapter.algo = &rtl2830_tuner_i2c_algo; 712c0adca734013389ac81513da546947e75d95151aAntti Palosaari priv->tuner_i2c_adapter.algo_data = NULL; 713eed5b0cfb4f1ac0715106b79b24f19fad6000416Antti Palosaari priv->tuner_i2c_adapter.dev.parent = &i2c->dev; 714c0adca734013389ac81513da546947e75d95151aAntti Palosaari i2c_set_adapdata(&priv->tuner_i2c_adapter, priv); 715c0adca734013389ac81513da546947e75d95151aAntti Palosaari if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) { 71686ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_err(&i2c->dev, 71786ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari "%s: tuner i2c bus could not be initialized\n", 71886ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari KBUILD_MODNAME); 719c0adca734013389ac81513da546947e75d95151aAntti Palosaari goto err; 720c0adca734013389ac81513da546947e75d95151aAntti Palosaari } 721c0adca734013389ac81513da546947e75d95151aAntti Palosaari 722a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari priv->sleeping = true; 723a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari 724c0adca734013389ac81513da546947e75d95151aAntti Palosaari return &priv->fe; 725c0adca734013389ac81513da546947e75d95151aAntti Palosaarierr: 72686ad0f1dd72b39159065fdf089afe0913b9bef41Antti Palosaari dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret); 727c0adca734013389ac81513da546947e75d95151aAntti Palosaari kfree(priv); 728c0adca734013389ac81513da546947e75d95151aAntti Palosaari return NULL; 729c0adca734013389ac81513da546947e75d95151aAntti Palosaari} 730c0adca734013389ac81513da546947e75d95151aAntti PalosaariEXPORT_SYMBOL(rtl2830_attach); 731c0adca734013389ac81513da546947e75d95151aAntti Palosaari 732c0adca734013389ac81513da546947e75d95151aAntti Palosaaristatic struct dvb_frontend_ops rtl2830_ops = { 733c0adca734013389ac81513da546947e75d95151aAntti Palosaari .delsys = { SYS_DVBT }, 734c0adca734013389ac81513da546947e75d95151aAntti Palosaari .info = { 735c0adca734013389ac81513da546947e75d95151aAntti Palosaari .name = "Realtek RTL2830 (DVB-T)", 736c0adca734013389ac81513da546947e75d95151aAntti Palosaari .caps = FE_CAN_FEC_1_2 | 737c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_FEC_2_3 | 738c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_FEC_3_4 | 739c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_FEC_5_6 | 740c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_FEC_7_8 | 741c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_FEC_AUTO | 742c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_QPSK | 743c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_QAM_16 | 744c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_QAM_64 | 745c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_QAM_AUTO | 746c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_TRANSMISSION_MODE_AUTO | 747c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_GUARD_INTERVAL_AUTO | 748c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_HIERARCHY_AUTO | 749c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_RECOVER | 750c0adca734013389ac81513da546947e75d95151aAntti Palosaari FE_CAN_MUTE_TS 751c0adca734013389ac81513da546947e75d95151aAntti Palosaari }, 752c0adca734013389ac81513da546947e75d95151aAntti Palosaari 753c0adca734013389ac81513da546947e75d95151aAntti Palosaari .release = rtl2830_release, 754c0adca734013389ac81513da546947e75d95151aAntti Palosaari 755c0adca734013389ac81513da546947e75d95151aAntti Palosaari .init = rtl2830_init, 756a8567cf22e0efb9faafa6cf33b607ca5aee3c2faAntti Palosaari .sleep = rtl2830_sleep, 757c0adca734013389ac81513da546947e75d95151aAntti Palosaari 758c0adca734013389ac81513da546947e75d95151aAntti Palosaari .get_tune_settings = rtl2830_get_tune_settings, 759c0adca734013389ac81513da546947e75d95151aAntti Palosaari 760c0adca734013389ac81513da546947e75d95151aAntti Palosaari .set_frontend = rtl2830_set_frontend, 761631a2b611288f87de4ef1098d1fb4bc4d246b103Antti Palosaari .get_frontend = rtl2830_get_frontend, 762c0adca734013389ac81513da546947e75d95151aAntti Palosaari 763c0adca734013389ac81513da546947e75d95151aAntti Palosaari .read_status = rtl2830_read_status, 764c0adca734013389ac81513da546947e75d95151aAntti Palosaari .read_snr = rtl2830_read_snr, 765c0adca734013389ac81513da546947e75d95151aAntti Palosaari .read_ber = rtl2830_read_ber, 766c0adca734013389ac81513da546947e75d95151aAntti Palosaari .read_ucblocks = rtl2830_read_ucblocks, 767c0adca734013389ac81513da546947e75d95151aAntti Palosaari .read_signal_strength = rtl2830_read_signal_strength, 768c0adca734013389ac81513da546947e75d95151aAntti Palosaari}; 769c0adca734013389ac81513da546947e75d95151aAntti Palosaari 770c0adca734013389ac81513da546947e75d95151aAntti PalosaariMODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 771c0adca734013389ac81513da546947e75d95151aAntti PalosaariMODULE_DESCRIPTION("Realtek RTL2830 DVB-T demodulator driver"); 772c0adca734013389ac81513da546947e75d95151aAntti PalosaariMODULE_LICENSE("GPL"); 773