19a0bf528SMauro Carvalho Chehab /* 29a0bf528SMauro Carvalho Chehab * Support for LG2160 - ATSC/MH 39a0bf528SMauro Carvalho Chehab * 49a0bf528SMauro Carvalho Chehab * Copyright (C) 2010 Michael Krufky <mkrufky@linuxtv.org> 59a0bf528SMauro Carvalho Chehab * 69a0bf528SMauro Carvalho Chehab * This program is free software; you can redistribute it and/or modify 79a0bf528SMauro Carvalho Chehab * it under the terms of the GNU General Public License as published by 89a0bf528SMauro Carvalho Chehab * the Free Software Foundation; either version 2 of the License, or 99a0bf528SMauro Carvalho Chehab * (at your option) any later version. 109a0bf528SMauro Carvalho Chehab * 119a0bf528SMauro Carvalho Chehab * This program is distributed in the hope that it will be useful, 129a0bf528SMauro Carvalho Chehab * but WITHOUT ANY WARRANTY; without even the implied warranty of 139a0bf528SMauro Carvalho Chehab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 149a0bf528SMauro Carvalho Chehab * GNU General Public License for more details. 159a0bf528SMauro Carvalho Chehab * 169a0bf528SMauro Carvalho Chehab * You should have received a copy of the GNU General Public License 179a0bf528SMauro Carvalho Chehab * along with this program; if not, write to the Free Software 189a0bf528SMauro Carvalho Chehab * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 199a0bf528SMauro Carvalho Chehab * 209a0bf528SMauro Carvalho Chehab */ 219a0bf528SMauro Carvalho Chehab 229a0bf528SMauro Carvalho Chehab #include <linux/jiffies.h> 239a0bf528SMauro Carvalho Chehab #include <linux/dvb/frontend.h> 249a0bf528SMauro Carvalho Chehab #include "lg2160.h" 259a0bf528SMauro Carvalho Chehab 269a0bf528SMauro Carvalho Chehab static int debug; 279a0bf528SMauro Carvalho Chehab module_param(debug, int, 0644); 289a0bf528SMauro Carvalho Chehab MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))"); 299a0bf528SMauro Carvalho Chehab 309a0bf528SMauro Carvalho Chehab #define DBG_INFO 1 319a0bf528SMauro Carvalho Chehab #define DBG_REG 2 329a0bf528SMauro Carvalho Chehab 339a0bf528SMauro Carvalho Chehab #define lg_printk(kern, fmt, arg...) \ 349a0bf528SMauro Carvalho Chehab printk(kern "%s: " fmt, __func__, ##arg) 359a0bf528SMauro Carvalho Chehab 369a0bf528SMauro Carvalho Chehab #define lg_info(fmt, arg...) printk(KERN_INFO "lg2160: " fmt, ##arg) 379a0bf528SMauro Carvalho Chehab #define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg) 389a0bf528SMauro Carvalho Chehab #define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg) 399a0bf528SMauro Carvalho Chehab #define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \ 409a0bf528SMauro Carvalho Chehab lg_printk(KERN_DEBUG, fmt, ##arg) 419a0bf528SMauro Carvalho Chehab #define lg_reg(fmt, arg...) if (debug & DBG_REG) \ 429a0bf528SMauro Carvalho Chehab lg_printk(KERN_DEBUG, fmt, ##arg) 439a0bf528SMauro Carvalho Chehab 449a0bf528SMauro Carvalho Chehab #define lg_fail(ret) \ 459a0bf528SMauro Carvalho Chehab ({ \ 469a0bf528SMauro Carvalho Chehab int __ret; \ 479a0bf528SMauro Carvalho Chehab __ret = (ret < 0); \ 489a0bf528SMauro Carvalho Chehab if (__ret) \ 499a0bf528SMauro Carvalho Chehab lg_err("error %d on line %d\n", ret, __LINE__); \ 509a0bf528SMauro Carvalho Chehab __ret; \ 519a0bf528SMauro Carvalho Chehab }) 529a0bf528SMauro Carvalho Chehab 539a0bf528SMauro Carvalho Chehab struct lg216x_state { 549a0bf528SMauro Carvalho Chehab struct i2c_adapter *i2c_adap; 559a0bf528SMauro Carvalho Chehab const struct lg2160_config *cfg; 569a0bf528SMauro Carvalho Chehab 579a0bf528SMauro Carvalho Chehab struct dvb_frontend frontend; 589a0bf528SMauro Carvalho Chehab 599a0bf528SMauro Carvalho Chehab u32 current_frequency; 609a0bf528SMauro Carvalho Chehab u8 parade_id; 619a0bf528SMauro Carvalho Chehab u8 fic_ver; 629a0bf528SMauro Carvalho Chehab unsigned int last_reset; 639a0bf528SMauro Carvalho Chehab }; 649a0bf528SMauro Carvalho Chehab 659a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 669a0bf528SMauro Carvalho Chehab 679a0bf528SMauro Carvalho Chehab static int lg216x_write_reg(struct lg216x_state *state, u16 reg, u8 val) 689a0bf528SMauro Carvalho Chehab { 699a0bf528SMauro Carvalho Chehab int ret; 709a0bf528SMauro Carvalho Chehab u8 buf[] = { reg >> 8, reg & 0xff, val }; 719a0bf528SMauro Carvalho Chehab struct i2c_msg msg = { 729a0bf528SMauro Carvalho Chehab .addr = state->cfg->i2c_addr, .flags = 0, 739a0bf528SMauro Carvalho Chehab .buf = buf, .len = 3, 749a0bf528SMauro Carvalho Chehab }; 759a0bf528SMauro Carvalho Chehab 769a0bf528SMauro Carvalho Chehab lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val); 779a0bf528SMauro Carvalho Chehab 789a0bf528SMauro Carvalho Chehab ret = i2c_transfer(state->i2c_adap, &msg, 1); 799a0bf528SMauro Carvalho Chehab 809a0bf528SMauro Carvalho Chehab if (ret != 1) { 819a0bf528SMauro Carvalho Chehab lg_err("error (addr %02x %02x <- %02x, err = %i)\n", 829a0bf528SMauro Carvalho Chehab msg.buf[0], msg.buf[1], msg.buf[2], ret); 839a0bf528SMauro Carvalho Chehab if (ret < 0) 849a0bf528SMauro Carvalho Chehab return ret; 859a0bf528SMauro Carvalho Chehab else 869a0bf528SMauro Carvalho Chehab return -EREMOTEIO; 879a0bf528SMauro Carvalho Chehab } 889a0bf528SMauro Carvalho Chehab return 0; 899a0bf528SMauro Carvalho Chehab } 909a0bf528SMauro Carvalho Chehab 919a0bf528SMauro Carvalho Chehab static int lg216x_read_reg(struct lg216x_state *state, u16 reg, u8 *val) 929a0bf528SMauro Carvalho Chehab { 939a0bf528SMauro Carvalho Chehab int ret; 949a0bf528SMauro Carvalho Chehab u8 reg_buf[] = { reg >> 8, reg & 0xff }; 959a0bf528SMauro Carvalho Chehab struct i2c_msg msg[] = { 969a0bf528SMauro Carvalho Chehab { .addr = state->cfg->i2c_addr, 979a0bf528SMauro Carvalho Chehab .flags = 0, .buf = reg_buf, .len = 2 }, 989a0bf528SMauro Carvalho Chehab { .addr = state->cfg->i2c_addr, 999a0bf528SMauro Carvalho Chehab .flags = I2C_M_RD, .buf = val, .len = 1 }, 1009a0bf528SMauro Carvalho Chehab }; 1019a0bf528SMauro Carvalho Chehab 1029a0bf528SMauro Carvalho Chehab lg_reg("reg: 0x%04x\n", reg); 1039a0bf528SMauro Carvalho Chehab 1049a0bf528SMauro Carvalho Chehab ret = i2c_transfer(state->i2c_adap, msg, 2); 1059a0bf528SMauro Carvalho Chehab 1069a0bf528SMauro Carvalho Chehab if (ret != 2) { 1079a0bf528SMauro Carvalho Chehab lg_err("error (addr %02x reg %04x error (ret == %i)\n", 1089a0bf528SMauro Carvalho Chehab state->cfg->i2c_addr, reg, ret); 1099a0bf528SMauro Carvalho Chehab if (ret < 0) 1109a0bf528SMauro Carvalho Chehab return ret; 1119a0bf528SMauro Carvalho Chehab else 1129a0bf528SMauro Carvalho Chehab return -EREMOTEIO; 1139a0bf528SMauro Carvalho Chehab } 1149a0bf528SMauro Carvalho Chehab return 0; 1159a0bf528SMauro Carvalho Chehab } 1169a0bf528SMauro Carvalho Chehab 1179a0bf528SMauro Carvalho Chehab struct lg216x_reg { 1189a0bf528SMauro Carvalho Chehab u16 reg; 1199a0bf528SMauro Carvalho Chehab u8 val; 1209a0bf528SMauro Carvalho Chehab }; 1219a0bf528SMauro Carvalho Chehab 1229a0bf528SMauro Carvalho Chehab static int lg216x_write_regs(struct lg216x_state *state, 1239a0bf528SMauro Carvalho Chehab struct lg216x_reg *regs, int len) 1249a0bf528SMauro Carvalho Chehab { 1259a0bf528SMauro Carvalho Chehab int i, ret; 1269a0bf528SMauro Carvalho Chehab 1279a0bf528SMauro Carvalho Chehab lg_reg("writing %d registers...\n", len); 1289a0bf528SMauro Carvalho Chehab 1299a0bf528SMauro Carvalho Chehab for (i = 0; i < len; i++) { 1309a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); 1319a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 1329a0bf528SMauro Carvalho Chehab return ret; 1339a0bf528SMauro Carvalho Chehab } 1349a0bf528SMauro Carvalho Chehab return 0; 1359a0bf528SMauro Carvalho Chehab } 1369a0bf528SMauro Carvalho Chehab 1379a0bf528SMauro Carvalho Chehab static int lg216x_set_reg_bit(struct lg216x_state *state, 1389a0bf528SMauro Carvalho Chehab u16 reg, int bit, int onoff) 1399a0bf528SMauro Carvalho Chehab { 1409a0bf528SMauro Carvalho Chehab u8 val; 1419a0bf528SMauro Carvalho Chehab int ret; 1429a0bf528SMauro Carvalho Chehab 1439a0bf528SMauro Carvalho Chehab lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff); 1449a0bf528SMauro Carvalho Chehab 1459a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, reg, &val); 1469a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 1479a0bf528SMauro Carvalho Chehab goto fail; 1489a0bf528SMauro Carvalho Chehab 1499a0bf528SMauro Carvalho Chehab val &= ~(1 << bit); 1509a0bf528SMauro Carvalho Chehab val |= (onoff & 1) << bit; 1519a0bf528SMauro Carvalho Chehab 1529a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, reg, val); 1539a0bf528SMauro Carvalho Chehab lg_fail(ret); 1549a0bf528SMauro Carvalho Chehab fail: 1559a0bf528SMauro Carvalho Chehab return ret; 1569a0bf528SMauro Carvalho Chehab } 1579a0bf528SMauro Carvalho Chehab 1589a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 1599a0bf528SMauro Carvalho Chehab 1609a0bf528SMauro Carvalho Chehab static int lg216x_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 1619a0bf528SMauro Carvalho Chehab { 1629a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 1639a0bf528SMauro Carvalho Chehab int ret; 1649a0bf528SMauro Carvalho Chehab 1659a0bf528SMauro Carvalho Chehab if (state->cfg->deny_i2c_rptr) 1669a0bf528SMauro Carvalho Chehab return 0; 1679a0bf528SMauro Carvalho Chehab 1689a0bf528SMauro Carvalho Chehab lg_dbg("(%d)\n", enable); 1699a0bf528SMauro Carvalho Chehab 1709a0bf528SMauro Carvalho Chehab ret = lg216x_set_reg_bit(state, 0x0000, 0, enable ? 0 : 1); 1719a0bf528SMauro Carvalho Chehab 1729a0bf528SMauro Carvalho Chehab msleep(1); 1739a0bf528SMauro Carvalho Chehab 1749a0bf528SMauro Carvalho Chehab return ret; 1759a0bf528SMauro Carvalho Chehab } 1769a0bf528SMauro Carvalho Chehab 1779a0bf528SMauro Carvalho Chehab static int lg216x_soft_reset(struct lg216x_state *state) 1789a0bf528SMauro Carvalho Chehab { 1799a0bf528SMauro Carvalho Chehab int ret; 1809a0bf528SMauro Carvalho Chehab 1819a0bf528SMauro Carvalho Chehab lg_dbg("\n"); 1829a0bf528SMauro Carvalho Chehab 1839a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0002, 0x00); 1849a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 1859a0bf528SMauro Carvalho Chehab goto fail; 1869a0bf528SMauro Carvalho Chehab 1879a0bf528SMauro Carvalho Chehab msleep(20); 1889a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0002, 0x01); 1899a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 1909a0bf528SMauro Carvalho Chehab goto fail; 1919a0bf528SMauro Carvalho Chehab 1929a0bf528SMauro Carvalho Chehab state->last_reset = jiffies_to_msecs(jiffies); 1939a0bf528SMauro Carvalho Chehab fail: 1949a0bf528SMauro Carvalho Chehab return ret; 1959a0bf528SMauro Carvalho Chehab } 1969a0bf528SMauro Carvalho Chehab 1979a0bf528SMauro Carvalho Chehab static int lg216x_initialize(struct lg216x_state *state) 1989a0bf528SMauro Carvalho Chehab { 1999a0bf528SMauro Carvalho Chehab int ret; 2009a0bf528SMauro Carvalho Chehab 2019a0bf528SMauro Carvalho Chehab static struct lg216x_reg lg2160_init[] = { 2029a0bf528SMauro Carvalho Chehab #if 0 2039a0bf528SMauro Carvalho Chehab { .reg = 0x0015, .val = 0xe6 }, 2049a0bf528SMauro Carvalho Chehab #else 2059a0bf528SMauro Carvalho Chehab { .reg = 0x0015, .val = 0xf7 }, 2069a0bf528SMauro Carvalho Chehab { .reg = 0x001b, .val = 0x52 }, 2079a0bf528SMauro Carvalho Chehab { .reg = 0x0208, .val = 0x00 }, 2089a0bf528SMauro Carvalho Chehab { .reg = 0x0209, .val = 0x82 }, 2099a0bf528SMauro Carvalho Chehab { .reg = 0x0210, .val = 0xf9 }, 2109a0bf528SMauro Carvalho Chehab { .reg = 0x020a, .val = 0x00 }, 2119a0bf528SMauro Carvalho Chehab { .reg = 0x020b, .val = 0x82 }, 2129a0bf528SMauro Carvalho Chehab { .reg = 0x020d, .val = 0x28 }, 2139a0bf528SMauro Carvalho Chehab { .reg = 0x020f, .val = 0x14 }, 2149a0bf528SMauro Carvalho Chehab #endif 2159a0bf528SMauro Carvalho Chehab }; 2169a0bf528SMauro Carvalho Chehab 2179a0bf528SMauro Carvalho Chehab static struct lg216x_reg lg2161_init[] = { 2189a0bf528SMauro Carvalho Chehab { .reg = 0x0000, .val = 0x41 }, 2199a0bf528SMauro Carvalho Chehab { .reg = 0x0001, .val = 0xfb }, 2209a0bf528SMauro Carvalho Chehab { .reg = 0x0216, .val = 0x00 }, 2219a0bf528SMauro Carvalho Chehab { .reg = 0x0219, .val = 0x00 }, 2229a0bf528SMauro Carvalho Chehab { .reg = 0x021b, .val = 0x55 }, 2239a0bf528SMauro Carvalho Chehab { .reg = 0x0606, .val = 0x0a }, 2249a0bf528SMauro Carvalho Chehab }; 2259a0bf528SMauro Carvalho Chehab 2269a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 2279a0bf528SMauro Carvalho Chehab case LG2160: 2289a0bf528SMauro Carvalho Chehab ret = lg216x_write_regs(state, 2299a0bf528SMauro Carvalho Chehab lg2160_init, ARRAY_SIZE(lg2160_init)); 2309a0bf528SMauro Carvalho Chehab break; 2319a0bf528SMauro Carvalho Chehab case LG2161: 2329a0bf528SMauro Carvalho Chehab ret = lg216x_write_regs(state, 2339a0bf528SMauro Carvalho Chehab lg2161_init, ARRAY_SIZE(lg2161_init)); 2349a0bf528SMauro Carvalho Chehab break; 2359a0bf528SMauro Carvalho Chehab default: 2369a0bf528SMauro Carvalho Chehab ret = -EINVAL; 2379a0bf528SMauro Carvalho Chehab break; 2389a0bf528SMauro Carvalho Chehab } 2399a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 2409a0bf528SMauro Carvalho Chehab goto fail; 2419a0bf528SMauro Carvalho Chehab 2429a0bf528SMauro Carvalho Chehab ret = lg216x_soft_reset(state); 2439a0bf528SMauro Carvalho Chehab lg_fail(ret); 2449a0bf528SMauro Carvalho Chehab fail: 2459a0bf528SMauro Carvalho Chehab return ret; 2469a0bf528SMauro Carvalho Chehab } 2479a0bf528SMauro Carvalho Chehab 2489a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 2499a0bf528SMauro Carvalho Chehab 2509a0bf528SMauro Carvalho Chehab static int lg216x_set_if(struct lg216x_state *state) 2519a0bf528SMauro Carvalho Chehab { 2529a0bf528SMauro Carvalho Chehab u8 val; 2539a0bf528SMauro Carvalho Chehab int ret; 2549a0bf528SMauro Carvalho Chehab 2559a0bf528SMauro Carvalho Chehab lg_dbg("%d KHz\n", state->cfg->if_khz); 2569a0bf528SMauro Carvalho Chehab 2579a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0132, &val); 2589a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 2599a0bf528SMauro Carvalho Chehab goto fail; 2609a0bf528SMauro Carvalho Chehab 2619a0bf528SMauro Carvalho Chehab val &= 0xfb; 2629a0bf528SMauro Carvalho Chehab val |= (0 == state->cfg->if_khz) ? 0x04 : 0x00; 2639a0bf528SMauro Carvalho Chehab 2649a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0132, val); 2659a0bf528SMauro Carvalho Chehab lg_fail(ret); 2669a0bf528SMauro Carvalho Chehab 2679a0bf528SMauro Carvalho Chehab /* if NOT zero IF, 6 MHz is the default */ 2689a0bf528SMauro Carvalho Chehab fail: 2699a0bf528SMauro Carvalho Chehab return ret; 2709a0bf528SMauro Carvalho Chehab } 2719a0bf528SMauro Carvalho Chehab 2729a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 2739a0bf528SMauro Carvalho Chehab 2749a0bf528SMauro Carvalho Chehab static int lg2160_agc_fix(struct lg216x_state *state, 2759a0bf528SMauro Carvalho Chehab int if_agc_fix, int rf_agc_fix) 2769a0bf528SMauro Carvalho Chehab { 2779a0bf528SMauro Carvalho Chehab u8 val; 2789a0bf528SMauro Carvalho Chehab int ret; 2799a0bf528SMauro Carvalho Chehab 2809a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0100, &val); 2819a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 2829a0bf528SMauro Carvalho Chehab goto fail; 2839a0bf528SMauro Carvalho Chehab 2849a0bf528SMauro Carvalho Chehab val &= 0xf3; 2859a0bf528SMauro Carvalho Chehab val |= (if_agc_fix) ? 0x08 : 0x00; 2869a0bf528SMauro Carvalho Chehab val |= (rf_agc_fix) ? 0x04 : 0x00; 2879a0bf528SMauro Carvalho Chehab 2889a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0100, val); 2899a0bf528SMauro Carvalho Chehab lg_fail(ret); 2909a0bf528SMauro Carvalho Chehab fail: 2919a0bf528SMauro Carvalho Chehab return ret; 2929a0bf528SMauro Carvalho Chehab } 2939a0bf528SMauro Carvalho Chehab 2949a0bf528SMauro Carvalho Chehab #if 0 2959a0bf528SMauro Carvalho Chehab static int lg2160_agc_freeze(struct lg216x_state *state, 2969a0bf528SMauro Carvalho Chehab int if_agc_freeze, int rf_agc_freeze) 2979a0bf528SMauro Carvalho Chehab { 2989a0bf528SMauro Carvalho Chehab u8 val; 2999a0bf528SMauro Carvalho Chehab int ret; 3009a0bf528SMauro Carvalho Chehab 3019a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0100, &val); 3029a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 3039a0bf528SMauro Carvalho Chehab goto fail; 3049a0bf528SMauro Carvalho Chehab 3059a0bf528SMauro Carvalho Chehab val &= 0xcf; 3069a0bf528SMauro Carvalho Chehab val |= (if_agc_freeze) ? 0x20 : 0x00; 3079a0bf528SMauro Carvalho Chehab val |= (rf_agc_freeze) ? 0x10 : 0x00; 3089a0bf528SMauro Carvalho Chehab 3099a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0100, val); 3109a0bf528SMauro Carvalho Chehab lg_fail(ret); 3119a0bf528SMauro Carvalho Chehab fail: 3129a0bf528SMauro Carvalho Chehab return ret; 3139a0bf528SMauro Carvalho Chehab } 3149a0bf528SMauro Carvalho Chehab #endif 3159a0bf528SMauro Carvalho Chehab 3169a0bf528SMauro Carvalho Chehab static int lg2160_agc_polarity(struct lg216x_state *state, 3179a0bf528SMauro Carvalho Chehab int if_agc_polarity, int rf_agc_polarity) 3189a0bf528SMauro Carvalho Chehab { 3199a0bf528SMauro Carvalho Chehab u8 val; 3209a0bf528SMauro Carvalho Chehab int ret; 3219a0bf528SMauro Carvalho Chehab 3229a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0100, &val); 3239a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 3249a0bf528SMauro Carvalho Chehab goto fail; 3259a0bf528SMauro Carvalho Chehab 3269a0bf528SMauro Carvalho Chehab val &= 0xfc; 3279a0bf528SMauro Carvalho Chehab val |= (if_agc_polarity) ? 0x02 : 0x00; 3289a0bf528SMauro Carvalho Chehab val |= (rf_agc_polarity) ? 0x01 : 0x00; 3299a0bf528SMauro Carvalho Chehab 3309a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0100, val); 3319a0bf528SMauro Carvalho Chehab lg_fail(ret); 3329a0bf528SMauro Carvalho Chehab fail: 3339a0bf528SMauro Carvalho Chehab return ret; 3349a0bf528SMauro Carvalho Chehab } 3359a0bf528SMauro Carvalho Chehab 3369a0bf528SMauro Carvalho Chehab static int lg2160_tuner_pwr_save_polarity(struct lg216x_state *state, 3379a0bf528SMauro Carvalho Chehab int polarity) 3389a0bf528SMauro Carvalho Chehab { 3399a0bf528SMauro Carvalho Chehab u8 val; 3409a0bf528SMauro Carvalho Chehab int ret; 3419a0bf528SMauro Carvalho Chehab 3429a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0008, &val); 3439a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 3449a0bf528SMauro Carvalho Chehab goto fail; 3459a0bf528SMauro Carvalho Chehab 3469a0bf528SMauro Carvalho Chehab val &= 0xfe; 3479a0bf528SMauro Carvalho Chehab val |= (polarity) ? 0x01 : 0x00; 3489a0bf528SMauro Carvalho Chehab 3499a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0008, val); 3509a0bf528SMauro Carvalho Chehab lg_fail(ret); 3519a0bf528SMauro Carvalho Chehab fail: 3529a0bf528SMauro Carvalho Chehab return ret; 3539a0bf528SMauro Carvalho Chehab } 3549a0bf528SMauro Carvalho Chehab 3559a0bf528SMauro Carvalho Chehab static int lg2160_spectrum_polarity(struct lg216x_state *state, 3569a0bf528SMauro Carvalho Chehab int inverted) 3579a0bf528SMauro Carvalho Chehab { 3589a0bf528SMauro Carvalho Chehab u8 val; 3599a0bf528SMauro Carvalho Chehab int ret; 3609a0bf528SMauro Carvalho Chehab 3619a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0132, &val); 3629a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 3639a0bf528SMauro Carvalho Chehab goto fail; 3649a0bf528SMauro Carvalho Chehab 3659a0bf528SMauro Carvalho Chehab val &= 0xfd; 3669a0bf528SMauro Carvalho Chehab val |= (inverted) ? 0x02 : 0x00; 3679a0bf528SMauro Carvalho Chehab 3689a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0132, val); 3699a0bf528SMauro Carvalho Chehab lg_fail(ret); 3709a0bf528SMauro Carvalho Chehab fail: 3719a0bf528SMauro Carvalho Chehab return lg216x_soft_reset(state); 3729a0bf528SMauro Carvalho Chehab } 3739a0bf528SMauro Carvalho Chehab 3749a0bf528SMauro Carvalho Chehab static int lg2160_tuner_pwr_save(struct lg216x_state *state, int onoff) 3759a0bf528SMauro Carvalho Chehab { 3769a0bf528SMauro Carvalho Chehab u8 val; 3779a0bf528SMauro Carvalho Chehab int ret; 3789a0bf528SMauro Carvalho Chehab 3799a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0007, &val); 3809a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 3819a0bf528SMauro Carvalho Chehab goto fail; 3829a0bf528SMauro Carvalho Chehab 3839a0bf528SMauro Carvalho Chehab val &= 0xbf; 3849a0bf528SMauro Carvalho Chehab val |= (onoff) ? 0x40 : 0x00; 3859a0bf528SMauro Carvalho Chehab 3869a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0007, val); 3879a0bf528SMauro Carvalho Chehab lg_fail(ret); 3889a0bf528SMauro Carvalho Chehab fail: 3899a0bf528SMauro Carvalho Chehab return ret; 3909a0bf528SMauro Carvalho Chehab } 3919a0bf528SMauro Carvalho Chehab 3929a0bf528SMauro Carvalho Chehab static int lg216x_set_parade(struct lg216x_state *state, int id) 3939a0bf528SMauro Carvalho Chehab { 3949a0bf528SMauro Carvalho Chehab int ret; 3959a0bf528SMauro Carvalho Chehab 3969a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x013e, id & 0x7f); 3979a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 3989a0bf528SMauro Carvalho Chehab goto fail; 3999a0bf528SMauro Carvalho Chehab 4009a0bf528SMauro Carvalho Chehab state->parade_id = id & 0x7f; 4019a0bf528SMauro Carvalho Chehab fail: 4029a0bf528SMauro Carvalho Chehab return ret; 4039a0bf528SMauro Carvalho Chehab } 4049a0bf528SMauro Carvalho Chehab 4059a0bf528SMauro Carvalho Chehab static int lg216x_set_ensemble(struct lg216x_state *state, int id) 4069a0bf528SMauro Carvalho Chehab { 4079a0bf528SMauro Carvalho Chehab int ret; 4089a0bf528SMauro Carvalho Chehab u16 reg; 4099a0bf528SMauro Carvalho Chehab u8 val; 4109a0bf528SMauro Carvalho Chehab 4119a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 4129a0bf528SMauro Carvalho Chehab case LG2160: 4139a0bf528SMauro Carvalho Chehab reg = 0x0400; 4149a0bf528SMauro Carvalho Chehab break; 4159a0bf528SMauro Carvalho Chehab case LG2161: 4169a0bf528SMauro Carvalho Chehab default: 4179a0bf528SMauro Carvalho Chehab reg = 0x0500; 4189a0bf528SMauro Carvalho Chehab break; 4199a0bf528SMauro Carvalho Chehab } 4209a0bf528SMauro Carvalho Chehab 4219a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, reg, &val); 4229a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4239a0bf528SMauro Carvalho Chehab goto fail; 4249a0bf528SMauro Carvalho Chehab 4259a0bf528SMauro Carvalho Chehab val &= 0xfe; 4269a0bf528SMauro Carvalho Chehab val |= (id) ? 0x01 : 0x00; 4279a0bf528SMauro Carvalho Chehab 4289a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, reg, val); 4299a0bf528SMauro Carvalho Chehab lg_fail(ret); 4309a0bf528SMauro Carvalho Chehab fail: 4319a0bf528SMauro Carvalho Chehab return ret; 4329a0bf528SMauro Carvalho Chehab } 4339a0bf528SMauro Carvalho Chehab 4349a0bf528SMauro Carvalho Chehab static int lg2160_set_spi_clock(struct lg216x_state *state) 4359a0bf528SMauro Carvalho Chehab { 4369a0bf528SMauro Carvalho Chehab u8 val; 4379a0bf528SMauro Carvalho Chehab int ret; 4389a0bf528SMauro Carvalho Chehab 4399a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0014, &val); 4409a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4419a0bf528SMauro Carvalho Chehab goto fail; 4429a0bf528SMauro Carvalho Chehab 4439a0bf528SMauro Carvalho Chehab val &= 0xf3; 4449a0bf528SMauro Carvalho Chehab val |= (state->cfg->spi_clock << 2); 4459a0bf528SMauro Carvalho Chehab 4469a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0014, val); 4479a0bf528SMauro Carvalho Chehab lg_fail(ret); 4489a0bf528SMauro Carvalho Chehab fail: 4499a0bf528SMauro Carvalho Chehab return ret; 4509a0bf528SMauro Carvalho Chehab } 4519a0bf528SMauro Carvalho Chehab 4529a0bf528SMauro Carvalho Chehab static int lg2161_set_output_interface(struct lg216x_state *state) 4539a0bf528SMauro Carvalho Chehab { 4549a0bf528SMauro Carvalho Chehab u8 val; 4559a0bf528SMauro Carvalho Chehab int ret; 4569a0bf528SMauro Carvalho Chehab 4579a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0014, &val); 4589a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4599a0bf528SMauro Carvalho Chehab goto fail; 4609a0bf528SMauro Carvalho Chehab 4619a0bf528SMauro Carvalho Chehab val &= ~0x07; 4629a0bf528SMauro Carvalho Chehab val |= state->cfg->output_if; /* FIXME: needs sanity check */ 4639a0bf528SMauro Carvalho Chehab 4649a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0014, val); 4659a0bf528SMauro Carvalho Chehab lg_fail(ret); 4669a0bf528SMauro Carvalho Chehab fail: 4679a0bf528SMauro Carvalho Chehab return ret; 4689a0bf528SMauro Carvalho Chehab } 4699a0bf528SMauro Carvalho Chehab 4709a0bf528SMauro Carvalho Chehab static int lg216x_enable_fic(struct lg216x_state *state, int onoff) 4719a0bf528SMauro Carvalho Chehab { 4729a0bf528SMauro Carvalho Chehab int ret; 4739a0bf528SMauro Carvalho Chehab 4749a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0017, 0x23); 4759a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4769a0bf528SMauro Carvalho Chehab goto fail; 4779a0bf528SMauro Carvalho Chehab 4789a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0016, 0xfc); 4799a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4809a0bf528SMauro Carvalho Chehab goto fail; 4819a0bf528SMauro Carvalho Chehab 4829a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 4839a0bf528SMauro Carvalho Chehab case LG2160: 4849a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0016, 4859a0bf528SMauro Carvalho Chehab 0xfc | ((onoff) ? 0x02 : 0x00)); 4869a0bf528SMauro Carvalho Chehab break; 4879a0bf528SMauro Carvalho Chehab case LG2161: 4889a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0016, (onoff) ? 0x10 : 0x00); 4899a0bf528SMauro Carvalho Chehab break; 4909a0bf528SMauro Carvalho Chehab } 4919a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4929a0bf528SMauro Carvalho Chehab goto fail; 4939a0bf528SMauro Carvalho Chehab 4949a0bf528SMauro Carvalho Chehab ret = lg216x_initialize(state); 4959a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 4969a0bf528SMauro Carvalho Chehab goto fail; 4979a0bf528SMauro Carvalho Chehab 4989a0bf528SMauro Carvalho Chehab if (onoff) { 4999a0bf528SMauro Carvalho Chehab ret = lg216x_write_reg(state, 0x0017, 0x03); 5009a0bf528SMauro Carvalho Chehab lg_fail(ret); 5019a0bf528SMauro Carvalho Chehab } 5029a0bf528SMauro Carvalho Chehab fail: 5039a0bf528SMauro Carvalho Chehab return ret; 5049a0bf528SMauro Carvalho Chehab } 5059a0bf528SMauro Carvalho Chehab 5069a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 5079a0bf528SMauro Carvalho Chehab 5089a0bf528SMauro Carvalho Chehab static int lg216x_get_fic_version(struct lg216x_state *state, u8 *ficver) 5099a0bf528SMauro Carvalho Chehab { 5109a0bf528SMauro Carvalho Chehab u8 val; 5119a0bf528SMauro Carvalho Chehab int ret; 5129a0bf528SMauro Carvalho Chehab 5139a0bf528SMauro Carvalho Chehab *ficver = 0xff; /* invalid value */ 5149a0bf528SMauro Carvalho Chehab 5159a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0128, &val); 5169a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 5179a0bf528SMauro Carvalho Chehab goto fail; 5189a0bf528SMauro Carvalho Chehab 5199a0bf528SMauro Carvalho Chehab *ficver = (val >> 3) & 0x1f; 5209a0bf528SMauro Carvalho Chehab fail: 5219a0bf528SMauro Carvalho Chehab return ret; 5229a0bf528SMauro Carvalho Chehab } 5239a0bf528SMauro Carvalho Chehab 5249a0bf528SMauro Carvalho Chehab #if 0 5259a0bf528SMauro Carvalho Chehab static int lg2160_get_parade_id(struct lg216x_state *state, u8 *id) 5269a0bf528SMauro Carvalho Chehab { 5279a0bf528SMauro Carvalho Chehab u8 val; 5289a0bf528SMauro Carvalho Chehab int ret; 5299a0bf528SMauro Carvalho Chehab 5309a0bf528SMauro Carvalho Chehab *id = 0xff; /* invalid value */ 5319a0bf528SMauro Carvalho Chehab 5329a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0123, &val); 5339a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 5349a0bf528SMauro Carvalho Chehab goto fail; 5359a0bf528SMauro Carvalho Chehab 5369a0bf528SMauro Carvalho Chehab *id = val & 0x7f; 5379a0bf528SMauro Carvalho Chehab fail: 5389a0bf528SMauro Carvalho Chehab return ret; 5399a0bf528SMauro Carvalho Chehab } 5409a0bf528SMauro Carvalho Chehab #endif 5419a0bf528SMauro Carvalho Chehab 5429a0bf528SMauro Carvalho Chehab static int lg216x_get_nog(struct lg216x_state *state, u8 *nog) 5439a0bf528SMauro Carvalho Chehab { 5449a0bf528SMauro Carvalho Chehab u8 val; 5459a0bf528SMauro Carvalho Chehab int ret; 5469a0bf528SMauro Carvalho Chehab 5479a0bf528SMauro Carvalho Chehab *nog = 0xff; /* invalid value */ 5489a0bf528SMauro Carvalho Chehab 5499a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0124, &val); 5509a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 5519a0bf528SMauro Carvalho Chehab goto fail; 5529a0bf528SMauro Carvalho Chehab 5539a0bf528SMauro Carvalho Chehab *nog = ((val >> 4) & 0x07) + 1; 5549a0bf528SMauro Carvalho Chehab fail: 5559a0bf528SMauro Carvalho Chehab return ret; 5569a0bf528SMauro Carvalho Chehab } 5579a0bf528SMauro Carvalho Chehab 5589a0bf528SMauro Carvalho Chehab static int lg216x_get_tnog(struct lg216x_state *state, u8 *tnog) 5599a0bf528SMauro Carvalho Chehab { 5609a0bf528SMauro Carvalho Chehab u8 val; 5619a0bf528SMauro Carvalho Chehab int ret; 5629a0bf528SMauro Carvalho Chehab 5639a0bf528SMauro Carvalho Chehab *tnog = 0xff; /* invalid value */ 5649a0bf528SMauro Carvalho Chehab 5659a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0125, &val); 5669a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 5679a0bf528SMauro Carvalho Chehab goto fail; 5689a0bf528SMauro Carvalho Chehab 5699a0bf528SMauro Carvalho Chehab *tnog = val & 0x1f; 5709a0bf528SMauro Carvalho Chehab fail: 5719a0bf528SMauro Carvalho Chehab return ret; 5729a0bf528SMauro Carvalho Chehab } 5739a0bf528SMauro Carvalho Chehab 5749a0bf528SMauro Carvalho Chehab static int lg216x_get_sgn(struct lg216x_state *state, u8 *sgn) 5759a0bf528SMauro Carvalho Chehab { 5769a0bf528SMauro Carvalho Chehab u8 val; 5779a0bf528SMauro Carvalho Chehab int ret; 5789a0bf528SMauro Carvalho Chehab 5799a0bf528SMauro Carvalho Chehab *sgn = 0xff; /* invalid value */ 5809a0bf528SMauro Carvalho Chehab 5819a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0124, &val); 5829a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 5839a0bf528SMauro Carvalho Chehab goto fail; 5849a0bf528SMauro Carvalho Chehab 5859a0bf528SMauro Carvalho Chehab *sgn = val & 0x0f; 5869a0bf528SMauro Carvalho Chehab fail: 5879a0bf528SMauro Carvalho Chehab return ret; 5889a0bf528SMauro Carvalho Chehab } 5899a0bf528SMauro Carvalho Chehab 5909a0bf528SMauro Carvalho Chehab static int lg216x_get_prc(struct lg216x_state *state, u8 *prc) 5919a0bf528SMauro Carvalho Chehab { 5929a0bf528SMauro Carvalho Chehab u8 val; 5939a0bf528SMauro Carvalho Chehab int ret; 5949a0bf528SMauro Carvalho Chehab 5959a0bf528SMauro Carvalho Chehab *prc = 0xff; /* invalid value */ 5969a0bf528SMauro Carvalho Chehab 5979a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0125, &val); 5989a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 5999a0bf528SMauro Carvalho Chehab goto fail; 6009a0bf528SMauro Carvalho Chehab 6019a0bf528SMauro Carvalho Chehab *prc = ((val >> 5) & 0x07) + 1; 6029a0bf528SMauro Carvalho Chehab fail: 6039a0bf528SMauro Carvalho Chehab return ret; 6049a0bf528SMauro Carvalho Chehab } 6059a0bf528SMauro Carvalho Chehab 6069a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 6079a0bf528SMauro Carvalho Chehab 6089a0bf528SMauro Carvalho Chehab static int lg216x_get_rs_frame_mode(struct lg216x_state *state, 6099a0bf528SMauro Carvalho Chehab enum atscmh_rs_frame_mode *rs_framemode) 6109a0bf528SMauro Carvalho Chehab { 6119a0bf528SMauro Carvalho Chehab u8 val; 6129a0bf528SMauro Carvalho Chehab int ret; 6139a0bf528SMauro Carvalho Chehab 6149a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 6159a0bf528SMauro Carvalho Chehab case LG2160: 6169a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0410, &val); 6179a0bf528SMauro Carvalho Chehab break; 6189a0bf528SMauro Carvalho Chehab case LG2161: 6199a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0513, &val); 6209a0bf528SMauro Carvalho Chehab break; 6219a0bf528SMauro Carvalho Chehab default: 6229a0bf528SMauro Carvalho Chehab ret = -EINVAL; 6239a0bf528SMauro Carvalho Chehab } 6249a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 6259a0bf528SMauro Carvalho Chehab goto fail; 6269a0bf528SMauro Carvalho Chehab 6279a0bf528SMauro Carvalho Chehab switch ((val >> 4) & 0x03) { 6289a0bf528SMauro Carvalho Chehab #if 1 6299a0bf528SMauro Carvalho Chehab default: 6309a0bf528SMauro Carvalho Chehab #endif 6319a0bf528SMauro Carvalho Chehab case 0x00: 6329a0bf528SMauro Carvalho Chehab *rs_framemode = ATSCMH_RSFRAME_PRI_ONLY; 6339a0bf528SMauro Carvalho Chehab break; 6349a0bf528SMauro Carvalho Chehab case 0x01: 6359a0bf528SMauro Carvalho Chehab *rs_framemode = ATSCMH_RSFRAME_PRI_SEC; 6369a0bf528SMauro Carvalho Chehab break; 6379a0bf528SMauro Carvalho Chehab #if 0 6389a0bf528SMauro Carvalho Chehab default: 6399a0bf528SMauro Carvalho Chehab *rs_framemode = ATSCMH_RSFRAME_RES; 6409a0bf528SMauro Carvalho Chehab break; 6419a0bf528SMauro Carvalho Chehab #endif 6429a0bf528SMauro Carvalho Chehab } 6439a0bf528SMauro Carvalho Chehab fail: 6449a0bf528SMauro Carvalho Chehab return ret; 6459a0bf528SMauro Carvalho Chehab } 6469a0bf528SMauro Carvalho Chehab 6479a0bf528SMauro Carvalho Chehab static 6489a0bf528SMauro Carvalho Chehab int lg216x_get_rs_frame_ensemble(struct lg216x_state *state, 6499a0bf528SMauro Carvalho Chehab enum atscmh_rs_frame_ensemble *rs_frame_ens) 6509a0bf528SMauro Carvalho Chehab { 6519a0bf528SMauro Carvalho Chehab u8 val; 6529a0bf528SMauro Carvalho Chehab int ret; 6539a0bf528SMauro Carvalho Chehab 6549a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 6559a0bf528SMauro Carvalho Chehab case LG2160: 6569a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0400, &val); 6579a0bf528SMauro Carvalho Chehab break; 6589a0bf528SMauro Carvalho Chehab case LG2161: 6599a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0500, &val); 6609a0bf528SMauro Carvalho Chehab break; 6619a0bf528SMauro Carvalho Chehab default: 6629a0bf528SMauro Carvalho Chehab ret = -EINVAL; 6639a0bf528SMauro Carvalho Chehab } 6649a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 6659a0bf528SMauro Carvalho Chehab goto fail; 6669a0bf528SMauro Carvalho Chehab 6679a0bf528SMauro Carvalho Chehab val &= 0x01; 6689a0bf528SMauro Carvalho Chehab *rs_frame_ens = (enum atscmh_rs_frame_ensemble) val; 6699a0bf528SMauro Carvalho Chehab fail: 6709a0bf528SMauro Carvalho Chehab return ret; 6719a0bf528SMauro Carvalho Chehab } 6729a0bf528SMauro Carvalho Chehab 6739a0bf528SMauro Carvalho Chehab static int lg216x_get_rs_code_mode(struct lg216x_state *state, 6749a0bf528SMauro Carvalho Chehab enum atscmh_rs_code_mode *rs_code_pri, 6759a0bf528SMauro Carvalho Chehab enum atscmh_rs_code_mode *rs_code_sec) 6769a0bf528SMauro Carvalho Chehab { 6779a0bf528SMauro Carvalho Chehab u8 val; 6789a0bf528SMauro Carvalho Chehab int ret; 6799a0bf528SMauro Carvalho Chehab 6809a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 6819a0bf528SMauro Carvalho Chehab case LG2160: 6829a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0410, &val); 6839a0bf528SMauro Carvalho Chehab break; 6849a0bf528SMauro Carvalho Chehab case LG2161: 6859a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0513, &val); 6869a0bf528SMauro Carvalho Chehab break; 6879a0bf528SMauro Carvalho Chehab default: 6889a0bf528SMauro Carvalho Chehab ret = -EINVAL; 6899a0bf528SMauro Carvalho Chehab } 6909a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 6919a0bf528SMauro Carvalho Chehab goto fail; 6929a0bf528SMauro Carvalho Chehab 6939a0bf528SMauro Carvalho Chehab *rs_code_pri = (enum atscmh_rs_code_mode) ((val >> 2) & 0x03); 6949a0bf528SMauro Carvalho Chehab *rs_code_sec = (enum atscmh_rs_code_mode) (val & 0x03); 6959a0bf528SMauro Carvalho Chehab fail: 6969a0bf528SMauro Carvalho Chehab return ret; 6979a0bf528SMauro Carvalho Chehab } 6989a0bf528SMauro Carvalho Chehab 6999a0bf528SMauro Carvalho Chehab static int lg216x_get_sccc_block_mode(struct lg216x_state *state, 7009a0bf528SMauro Carvalho Chehab enum atscmh_sccc_block_mode *sccc_block) 7019a0bf528SMauro Carvalho Chehab { 7029a0bf528SMauro Carvalho Chehab u8 val; 7039a0bf528SMauro Carvalho Chehab int ret; 7049a0bf528SMauro Carvalho Chehab 7059a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 7069a0bf528SMauro Carvalho Chehab case LG2160: 7079a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0315, &val); 7089a0bf528SMauro Carvalho Chehab break; 7099a0bf528SMauro Carvalho Chehab case LG2161: 7109a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0511, &val); 7119a0bf528SMauro Carvalho Chehab break; 7129a0bf528SMauro Carvalho Chehab default: 7139a0bf528SMauro Carvalho Chehab ret = -EINVAL; 7149a0bf528SMauro Carvalho Chehab } 7159a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 7169a0bf528SMauro Carvalho Chehab goto fail; 7179a0bf528SMauro Carvalho Chehab 7189a0bf528SMauro Carvalho Chehab switch (val & 0x03) { 7199a0bf528SMauro Carvalho Chehab case 0x00: 7209a0bf528SMauro Carvalho Chehab *sccc_block = ATSCMH_SCCC_BLK_SEP; 7219a0bf528SMauro Carvalho Chehab break; 7229a0bf528SMauro Carvalho Chehab case 0x01: 7239a0bf528SMauro Carvalho Chehab *sccc_block = ATSCMH_SCCC_BLK_COMB; 7249a0bf528SMauro Carvalho Chehab break; 7259a0bf528SMauro Carvalho Chehab default: 7269a0bf528SMauro Carvalho Chehab *sccc_block = ATSCMH_SCCC_BLK_RES; 7279a0bf528SMauro Carvalho Chehab break; 7289a0bf528SMauro Carvalho Chehab } 7299a0bf528SMauro Carvalho Chehab fail: 7309a0bf528SMauro Carvalho Chehab return ret; 7319a0bf528SMauro Carvalho Chehab } 7329a0bf528SMauro Carvalho Chehab 7339a0bf528SMauro Carvalho Chehab static int lg216x_get_sccc_code_mode(struct lg216x_state *state, 7349a0bf528SMauro Carvalho Chehab enum atscmh_sccc_code_mode *mode_a, 7359a0bf528SMauro Carvalho Chehab enum atscmh_sccc_code_mode *mode_b, 7369a0bf528SMauro Carvalho Chehab enum atscmh_sccc_code_mode *mode_c, 7379a0bf528SMauro Carvalho Chehab enum atscmh_sccc_code_mode *mode_d) 7389a0bf528SMauro Carvalho Chehab { 7399a0bf528SMauro Carvalho Chehab u8 val; 7409a0bf528SMauro Carvalho Chehab int ret; 7419a0bf528SMauro Carvalho Chehab 7429a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 7439a0bf528SMauro Carvalho Chehab case LG2160: 7449a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0316, &val); 7459a0bf528SMauro Carvalho Chehab break; 7469a0bf528SMauro Carvalho Chehab case LG2161: 7479a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0512, &val); 7489a0bf528SMauro Carvalho Chehab break; 7499a0bf528SMauro Carvalho Chehab default: 7509a0bf528SMauro Carvalho Chehab ret = -EINVAL; 7519a0bf528SMauro Carvalho Chehab } 7529a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 7539a0bf528SMauro Carvalho Chehab goto fail; 7549a0bf528SMauro Carvalho Chehab 7559a0bf528SMauro Carvalho Chehab switch ((val >> 6) & 0x03) { 7569a0bf528SMauro Carvalho Chehab case 0x00: 7579a0bf528SMauro Carvalho Chehab *mode_a = ATSCMH_SCCC_CODE_HLF; 7589a0bf528SMauro Carvalho Chehab break; 7599a0bf528SMauro Carvalho Chehab case 0x01: 7609a0bf528SMauro Carvalho Chehab *mode_a = ATSCMH_SCCC_CODE_QTR; 7619a0bf528SMauro Carvalho Chehab break; 7629a0bf528SMauro Carvalho Chehab default: 7639a0bf528SMauro Carvalho Chehab *mode_a = ATSCMH_SCCC_CODE_RES; 7649a0bf528SMauro Carvalho Chehab break; 7659a0bf528SMauro Carvalho Chehab } 7669a0bf528SMauro Carvalho Chehab 7679a0bf528SMauro Carvalho Chehab switch ((val >> 4) & 0x03) { 7689a0bf528SMauro Carvalho Chehab case 0x00: 7699a0bf528SMauro Carvalho Chehab *mode_b = ATSCMH_SCCC_CODE_HLF; 7709a0bf528SMauro Carvalho Chehab break; 7719a0bf528SMauro Carvalho Chehab case 0x01: 7729a0bf528SMauro Carvalho Chehab *mode_b = ATSCMH_SCCC_CODE_QTR; 7739a0bf528SMauro Carvalho Chehab break; 7749a0bf528SMauro Carvalho Chehab default: 7759a0bf528SMauro Carvalho Chehab *mode_b = ATSCMH_SCCC_CODE_RES; 7769a0bf528SMauro Carvalho Chehab break; 7779a0bf528SMauro Carvalho Chehab } 7789a0bf528SMauro Carvalho Chehab 7799a0bf528SMauro Carvalho Chehab switch ((val >> 2) & 0x03) { 7809a0bf528SMauro Carvalho Chehab case 0x00: 7819a0bf528SMauro Carvalho Chehab *mode_c = ATSCMH_SCCC_CODE_HLF; 7829a0bf528SMauro Carvalho Chehab break; 7839a0bf528SMauro Carvalho Chehab case 0x01: 7849a0bf528SMauro Carvalho Chehab *mode_c = ATSCMH_SCCC_CODE_QTR; 7859a0bf528SMauro Carvalho Chehab break; 7869a0bf528SMauro Carvalho Chehab default: 7879a0bf528SMauro Carvalho Chehab *mode_c = ATSCMH_SCCC_CODE_RES; 7889a0bf528SMauro Carvalho Chehab break; 7899a0bf528SMauro Carvalho Chehab } 7909a0bf528SMauro Carvalho Chehab 7919a0bf528SMauro Carvalho Chehab switch (val & 0x03) { 7929a0bf528SMauro Carvalho Chehab case 0x00: 7939a0bf528SMauro Carvalho Chehab *mode_d = ATSCMH_SCCC_CODE_HLF; 7949a0bf528SMauro Carvalho Chehab break; 7959a0bf528SMauro Carvalho Chehab case 0x01: 7969a0bf528SMauro Carvalho Chehab *mode_d = ATSCMH_SCCC_CODE_QTR; 7979a0bf528SMauro Carvalho Chehab break; 7989a0bf528SMauro Carvalho Chehab default: 7999a0bf528SMauro Carvalho Chehab *mode_d = ATSCMH_SCCC_CODE_RES; 8009a0bf528SMauro Carvalho Chehab break; 8019a0bf528SMauro Carvalho Chehab } 8029a0bf528SMauro Carvalho Chehab fail: 8039a0bf528SMauro Carvalho Chehab return ret; 8049a0bf528SMauro Carvalho Chehab } 8059a0bf528SMauro Carvalho Chehab 8069a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 8079a0bf528SMauro Carvalho Chehab 8089a0bf528SMauro Carvalho Chehab #if 0 8099a0bf528SMauro Carvalho Chehab static int lg216x_read_fic_err_count(struct lg216x_state *state, u8 *err) 8109a0bf528SMauro Carvalho Chehab { 8119a0bf528SMauro Carvalho Chehab u8 fic_err; 8129a0bf528SMauro Carvalho Chehab int ret; 8139a0bf528SMauro Carvalho Chehab 8149a0bf528SMauro Carvalho Chehab *err = 0; 8159a0bf528SMauro Carvalho Chehab 8169a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 8179a0bf528SMauro Carvalho Chehab case LG2160: 8189a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0012, &fic_err); 8199a0bf528SMauro Carvalho Chehab break; 8209a0bf528SMauro Carvalho Chehab case LG2161: 8219a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x001e, &fic_err); 8229a0bf528SMauro Carvalho Chehab break; 8239a0bf528SMauro Carvalho Chehab } 8249a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 8259a0bf528SMauro Carvalho Chehab goto fail; 8269a0bf528SMauro Carvalho Chehab 8279a0bf528SMauro Carvalho Chehab *err = fic_err; 8289a0bf528SMauro Carvalho Chehab fail: 8299a0bf528SMauro Carvalho Chehab return ret; 8309a0bf528SMauro Carvalho Chehab } 8319a0bf528SMauro Carvalho Chehab 8329a0bf528SMauro Carvalho Chehab static int lg2160_read_crc_err_count(struct lg216x_state *state, u16 *err) 8339a0bf528SMauro Carvalho Chehab { 8349a0bf528SMauro Carvalho Chehab u8 crc_err1, crc_err2; 8359a0bf528SMauro Carvalho Chehab int ret; 8369a0bf528SMauro Carvalho Chehab 8379a0bf528SMauro Carvalho Chehab *err = 0; 8389a0bf528SMauro Carvalho Chehab 8399a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0411, &crc_err1); 8409a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 8419a0bf528SMauro Carvalho Chehab goto fail; 8429a0bf528SMauro Carvalho Chehab 8439a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0412, &crc_err2); 8449a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 8459a0bf528SMauro Carvalho Chehab goto fail; 8469a0bf528SMauro Carvalho Chehab 8479a0bf528SMauro Carvalho Chehab *err = (u16)(((crc_err2 & 0x0f) << 8) | crc_err1); 8489a0bf528SMauro Carvalho Chehab fail: 8499a0bf528SMauro Carvalho Chehab return ret; 8509a0bf528SMauro Carvalho Chehab } 8519a0bf528SMauro Carvalho Chehab 8529a0bf528SMauro Carvalho Chehab static int lg2161_read_crc_err_count(struct lg216x_state *state, u16 *err) 8539a0bf528SMauro Carvalho Chehab { 8549a0bf528SMauro Carvalho Chehab u8 crc_err; 8559a0bf528SMauro Carvalho Chehab int ret; 8569a0bf528SMauro Carvalho Chehab 8579a0bf528SMauro Carvalho Chehab *err = 0; 8589a0bf528SMauro Carvalho Chehab 8599a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0612, &crc_err); 8609a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 8619a0bf528SMauro Carvalho Chehab goto fail; 8629a0bf528SMauro Carvalho Chehab 8639a0bf528SMauro Carvalho Chehab *err = (u16)crc_err; 8649a0bf528SMauro Carvalho Chehab fail: 8659a0bf528SMauro Carvalho Chehab return ret; 8669a0bf528SMauro Carvalho Chehab } 8679a0bf528SMauro Carvalho Chehab 8689a0bf528SMauro Carvalho Chehab static int lg216x_read_crc_err_count(struct lg216x_state *state, u16 *err) 8699a0bf528SMauro Carvalho Chehab { 8709a0bf528SMauro Carvalho Chehab int ret; 8719a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 8729a0bf528SMauro Carvalho Chehab case LG2160: 8739a0bf528SMauro Carvalho Chehab ret = lg2160_read_crc_err_count(state, err); 8749a0bf528SMauro Carvalho Chehab break; 8759a0bf528SMauro Carvalho Chehab case LG2161: 8769a0bf528SMauro Carvalho Chehab ret = lg2161_read_crc_err_count(state, err); 8779a0bf528SMauro Carvalho Chehab break; 8789a0bf528SMauro Carvalho Chehab default: 8799a0bf528SMauro Carvalho Chehab ret = -EINVAL; 8809a0bf528SMauro Carvalho Chehab break; 8819a0bf528SMauro Carvalho Chehab } 8829a0bf528SMauro Carvalho Chehab return ret; 8839a0bf528SMauro Carvalho Chehab } 8849a0bf528SMauro Carvalho Chehab 8859a0bf528SMauro Carvalho Chehab static int lg2160_read_rs_err_count(struct lg216x_state *state, u16 *err) 8869a0bf528SMauro Carvalho Chehab { 8879a0bf528SMauro Carvalho Chehab u8 rs_err1, rs_err2; 8889a0bf528SMauro Carvalho Chehab int ret; 8899a0bf528SMauro Carvalho Chehab 8909a0bf528SMauro Carvalho Chehab *err = 0; 8919a0bf528SMauro Carvalho Chehab 8929a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0413, &rs_err1); 8939a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 8949a0bf528SMauro Carvalho Chehab goto fail; 8959a0bf528SMauro Carvalho Chehab 8969a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0414, &rs_err2); 8979a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 8989a0bf528SMauro Carvalho Chehab goto fail; 8999a0bf528SMauro Carvalho Chehab 9009a0bf528SMauro Carvalho Chehab *err = (u16)(((rs_err2 & 0x0f) << 8) | rs_err1); 9019a0bf528SMauro Carvalho Chehab fail: 9029a0bf528SMauro Carvalho Chehab return ret; 9039a0bf528SMauro Carvalho Chehab } 9049a0bf528SMauro Carvalho Chehab 9059a0bf528SMauro Carvalho Chehab static int lg2161_read_rs_err_count(struct lg216x_state *state, u16 *err) 9069a0bf528SMauro Carvalho Chehab { 9079a0bf528SMauro Carvalho Chehab u8 rs_err1, rs_err2; 9089a0bf528SMauro Carvalho Chehab int ret; 9099a0bf528SMauro Carvalho Chehab 9109a0bf528SMauro Carvalho Chehab *err = 0; 9119a0bf528SMauro Carvalho Chehab 9129a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0613, &rs_err1); 9139a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9149a0bf528SMauro Carvalho Chehab goto fail; 9159a0bf528SMauro Carvalho Chehab 9169a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0614, &rs_err2); 9179a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9189a0bf528SMauro Carvalho Chehab goto fail; 9199a0bf528SMauro Carvalho Chehab 9209a0bf528SMauro Carvalho Chehab *err = (u16)((rs_err1 << 8) | rs_err2); 9219a0bf528SMauro Carvalho Chehab fail: 9229a0bf528SMauro Carvalho Chehab return ret; 9239a0bf528SMauro Carvalho Chehab } 9249a0bf528SMauro Carvalho Chehab 9259a0bf528SMauro Carvalho Chehab static int lg216x_read_rs_err_count(struct lg216x_state *state, u16 *err) 9269a0bf528SMauro Carvalho Chehab { 9279a0bf528SMauro Carvalho Chehab int ret; 9289a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 9299a0bf528SMauro Carvalho Chehab case LG2160: 9309a0bf528SMauro Carvalho Chehab ret = lg2160_read_rs_err_count(state, err); 9319a0bf528SMauro Carvalho Chehab break; 9329a0bf528SMauro Carvalho Chehab case LG2161: 9339a0bf528SMauro Carvalho Chehab ret = lg2161_read_rs_err_count(state, err); 9349a0bf528SMauro Carvalho Chehab break; 9359a0bf528SMauro Carvalho Chehab default: 9369a0bf528SMauro Carvalho Chehab ret = -EINVAL; 9379a0bf528SMauro Carvalho Chehab break; 9389a0bf528SMauro Carvalho Chehab } 9399a0bf528SMauro Carvalho Chehab return ret; 9409a0bf528SMauro Carvalho Chehab } 9419a0bf528SMauro Carvalho Chehab #endif 9429a0bf528SMauro Carvalho Chehab 9439a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 9449a0bf528SMauro Carvalho Chehab 9457e3e68bcSMauro Carvalho Chehab static int lg216x_get_frontend(struct dvb_frontend *fe, 9467e3e68bcSMauro Carvalho Chehab struct dtv_frontend_properties *c) 9479a0bf528SMauro Carvalho Chehab { 9489a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 9499a0bf528SMauro Carvalho Chehab int ret; 9509a0bf528SMauro Carvalho Chehab 9519a0bf528SMauro Carvalho Chehab lg_dbg("\n"); 9529a0bf528SMauro Carvalho Chehab 9537e3e68bcSMauro Carvalho Chehab c->modulation = VSB_8; 9547e3e68bcSMauro Carvalho Chehab c->frequency = state->current_frequency; 9557e3e68bcSMauro Carvalho Chehab c->delivery_system = SYS_ATSCMH; 9569a0bf528SMauro Carvalho Chehab 9579a0bf528SMauro Carvalho Chehab ret = lg216x_get_fic_version(state, 9587e3e68bcSMauro Carvalho Chehab &c->atscmh_fic_ver); 9599a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9609a0bf528SMauro Carvalho Chehab goto fail; 9617e3e68bcSMauro Carvalho Chehab if (state->fic_ver != c->atscmh_fic_ver) { 9627e3e68bcSMauro Carvalho Chehab state->fic_ver = c->atscmh_fic_ver; 9639a0bf528SMauro Carvalho Chehab 9649a0bf528SMauro Carvalho Chehab #if 0 9659a0bf528SMauro Carvalho Chehab ret = lg2160_get_parade_id(state, 9667e3e68bcSMauro Carvalho Chehab &c->atscmh_parade_id); 9679a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9689a0bf528SMauro Carvalho Chehab goto fail; 9699a0bf528SMauro Carvalho Chehab /* #else */ 9707e3e68bcSMauro Carvalho Chehab c->atscmh_parade_id = state->parade_id; 9719a0bf528SMauro Carvalho Chehab #endif 9729a0bf528SMauro Carvalho Chehab ret = lg216x_get_nog(state, 9737e3e68bcSMauro Carvalho Chehab &c->atscmh_nog); 9749a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9759a0bf528SMauro Carvalho Chehab goto fail; 9769a0bf528SMauro Carvalho Chehab ret = lg216x_get_tnog(state, 9777e3e68bcSMauro Carvalho Chehab &c->atscmh_tnog); 9789a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9799a0bf528SMauro Carvalho Chehab goto fail; 9809a0bf528SMauro Carvalho Chehab ret = lg216x_get_sgn(state, 9817e3e68bcSMauro Carvalho Chehab &c->atscmh_sgn); 9829a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9839a0bf528SMauro Carvalho Chehab goto fail; 9849a0bf528SMauro Carvalho Chehab ret = lg216x_get_prc(state, 9857e3e68bcSMauro Carvalho Chehab &c->atscmh_prc); 9869a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9879a0bf528SMauro Carvalho Chehab goto fail; 9889a0bf528SMauro Carvalho Chehab 9899a0bf528SMauro Carvalho Chehab ret = lg216x_get_rs_frame_mode(state, 9909a0bf528SMauro Carvalho Chehab (enum atscmh_rs_frame_mode *) 9917e3e68bcSMauro Carvalho Chehab &c->atscmh_rs_frame_mode); 9929a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9939a0bf528SMauro Carvalho Chehab goto fail; 9949a0bf528SMauro Carvalho Chehab ret = lg216x_get_rs_frame_ensemble(state, 9959a0bf528SMauro Carvalho Chehab (enum atscmh_rs_frame_ensemble *) 9967e3e68bcSMauro Carvalho Chehab &c->atscmh_rs_frame_ensemble); 9979a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 9989a0bf528SMauro Carvalho Chehab goto fail; 9999a0bf528SMauro Carvalho Chehab ret = lg216x_get_rs_code_mode(state, 10009a0bf528SMauro Carvalho Chehab (enum atscmh_rs_code_mode *) 10017e3e68bcSMauro Carvalho Chehab &c->atscmh_rs_code_mode_pri, 10029a0bf528SMauro Carvalho Chehab (enum atscmh_rs_code_mode *) 10037e3e68bcSMauro Carvalho Chehab &c->atscmh_rs_code_mode_sec); 10049a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10059a0bf528SMauro Carvalho Chehab goto fail; 10069a0bf528SMauro Carvalho Chehab ret = lg216x_get_sccc_block_mode(state, 10079a0bf528SMauro Carvalho Chehab (enum atscmh_sccc_block_mode *) 10087e3e68bcSMauro Carvalho Chehab &c->atscmh_sccc_block_mode); 10099a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10109a0bf528SMauro Carvalho Chehab goto fail; 10119a0bf528SMauro Carvalho Chehab ret = lg216x_get_sccc_code_mode(state, 10129a0bf528SMauro Carvalho Chehab (enum atscmh_sccc_code_mode *) 10137e3e68bcSMauro Carvalho Chehab &c->atscmh_sccc_code_mode_a, 10149a0bf528SMauro Carvalho Chehab (enum atscmh_sccc_code_mode *) 10157e3e68bcSMauro Carvalho Chehab &c->atscmh_sccc_code_mode_b, 10169a0bf528SMauro Carvalho Chehab (enum atscmh_sccc_code_mode *) 10177e3e68bcSMauro Carvalho Chehab &c->atscmh_sccc_code_mode_c, 10189a0bf528SMauro Carvalho Chehab (enum atscmh_sccc_code_mode *) 10197e3e68bcSMauro Carvalho Chehab &c->atscmh_sccc_code_mode_d); 10209a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10219a0bf528SMauro Carvalho Chehab goto fail; 10229a0bf528SMauro Carvalho Chehab } 10239a0bf528SMauro Carvalho Chehab #if 0 10249a0bf528SMauro Carvalho Chehab ret = lg216x_read_fic_err_count(state, 10257e3e68bcSMauro Carvalho Chehab (u8 *)&c->atscmh_fic_err); 10269a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10279a0bf528SMauro Carvalho Chehab goto fail; 10289a0bf528SMauro Carvalho Chehab ret = lg216x_read_crc_err_count(state, 10297e3e68bcSMauro Carvalho Chehab &c->atscmh_crc_err); 10309a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10319a0bf528SMauro Carvalho Chehab goto fail; 10329a0bf528SMauro Carvalho Chehab ret = lg216x_read_rs_err_count(state, 10337e3e68bcSMauro Carvalho Chehab &c->atscmh_rs_err); 10349a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10359a0bf528SMauro Carvalho Chehab goto fail; 10369a0bf528SMauro Carvalho Chehab 10379a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 10389a0bf528SMauro Carvalho Chehab case LG2160: 10397e3e68bcSMauro Carvalho Chehab if (((c->atscmh_rs_err >= 240) && 10407e3e68bcSMauro Carvalho Chehab (c->atscmh_crc_err >= 240)) && 10419a0bf528SMauro Carvalho Chehab ((jiffies_to_msecs(jiffies) - state->last_reset) > 6000)) 10429a0bf528SMauro Carvalho Chehab ret = lg216x_soft_reset(state); 10439a0bf528SMauro Carvalho Chehab break; 10449a0bf528SMauro Carvalho Chehab case LG2161: 10459a0bf528SMauro Carvalho Chehab /* no fix needed here (as far as we know) */ 10469a0bf528SMauro Carvalho Chehab ret = 0; 10479a0bf528SMauro Carvalho Chehab break; 10489a0bf528SMauro Carvalho Chehab } 10499a0bf528SMauro Carvalho Chehab lg_fail(ret); 10509a0bf528SMauro Carvalho Chehab #endif 10519a0bf528SMauro Carvalho Chehab fail: 10529a0bf528SMauro Carvalho Chehab return ret; 10539a0bf528SMauro Carvalho Chehab } 10549a0bf528SMauro Carvalho Chehab 10559a0bf528SMauro Carvalho Chehab static int lg216x_get_property(struct dvb_frontend *fe, 10569a0bf528SMauro Carvalho Chehab struct dtv_property *tvp) 10579a0bf528SMauro Carvalho Chehab { 10587e3e68bcSMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 10597e3e68bcSMauro Carvalho Chehab 10609a0bf528SMauro Carvalho Chehab return (DTV_ATSCMH_FIC_VER == tvp->cmd) ? 10617e3e68bcSMauro Carvalho Chehab lg216x_get_frontend(fe, c) : 0; 10629a0bf528SMauro Carvalho Chehab } 10639a0bf528SMauro Carvalho Chehab 10649a0bf528SMauro Carvalho Chehab 10659a0bf528SMauro Carvalho Chehab static int lg2160_set_frontend(struct dvb_frontend *fe) 10669a0bf528SMauro Carvalho Chehab { 10679a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 10687e3e68bcSMauro Carvalho Chehab struct dtv_frontend_properties *c = &fe->dtv_property_cache; 10699a0bf528SMauro Carvalho Chehab int ret; 10709a0bf528SMauro Carvalho Chehab 10719a0bf528SMauro Carvalho Chehab lg_dbg("(%d)\n", fe->dtv_property_cache.frequency); 10729a0bf528SMauro Carvalho Chehab 10739a0bf528SMauro Carvalho Chehab if (fe->ops.tuner_ops.set_params) { 10749a0bf528SMauro Carvalho Chehab ret = fe->ops.tuner_ops.set_params(fe); 10759a0bf528SMauro Carvalho Chehab if (fe->ops.i2c_gate_ctrl) 10769a0bf528SMauro Carvalho Chehab fe->ops.i2c_gate_ctrl(fe, 0); 10779a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10789a0bf528SMauro Carvalho Chehab goto fail; 10799a0bf528SMauro Carvalho Chehab state->current_frequency = fe->dtv_property_cache.frequency; 10809a0bf528SMauro Carvalho Chehab } 10819a0bf528SMauro Carvalho Chehab 10829a0bf528SMauro Carvalho Chehab ret = lg2160_agc_fix(state, 0, 0); 10839a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10849a0bf528SMauro Carvalho Chehab goto fail; 10859a0bf528SMauro Carvalho Chehab ret = lg2160_agc_polarity(state, 0, 0); 10869a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10879a0bf528SMauro Carvalho Chehab goto fail; 10889a0bf528SMauro Carvalho Chehab ret = lg2160_tuner_pwr_save_polarity(state, 1); 10899a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10909a0bf528SMauro Carvalho Chehab goto fail; 10919a0bf528SMauro Carvalho Chehab ret = lg216x_set_if(state); 10929a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10939a0bf528SMauro Carvalho Chehab goto fail; 10949a0bf528SMauro Carvalho Chehab ret = lg2160_spectrum_polarity(state, state->cfg->spectral_inversion); 10959a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 10969a0bf528SMauro Carvalho Chehab goto fail; 10979a0bf528SMauro Carvalho Chehab 10989a0bf528SMauro Carvalho Chehab /* be tuned before this point */ 10999a0bf528SMauro Carvalho Chehab ret = lg216x_soft_reset(state); 11009a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11019a0bf528SMauro Carvalho Chehab goto fail; 11029a0bf528SMauro Carvalho Chehab 11039a0bf528SMauro Carvalho Chehab ret = lg2160_tuner_pwr_save(state, 0); 11049a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11059a0bf528SMauro Carvalho Chehab goto fail; 11069a0bf528SMauro Carvalho Chehab 11079a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 11089a0bf528SMauro Carvalho Chehab case LG2160: 11099a0bf528SMauro Carvalho Chehab ret = lg2160_set_spi_clock(state); 11109a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11119a0bf528SMauro Carvalho Chehab goto fail; 11129a0bf528SMauro Carvalho Chehab break; 11139a0bf528SMauro Carvalho Chehab case LG2161: 11149a0bf528SMauro Carvalho Chehab ret = lg2161_set_output_interface(state); 11159a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11169a0bf528SMauro Carvalho Chehab goto fail; 11179a0bf528SMauro Carvalho Chehab break; 11189a0bf528SMauro Carvalho Chehab } 11199a0bf528SMauro Carvalho Chehab 11209a0bf528SMauro Carvalho Chehab ret = lg216x_set_parade(state, fe->dtv_property_cache.atscmh_parade_id); 11219a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11229a0bf528SMauro Carvalho Chehab goto fail; 11239a0bf528SMauro Carvalho Chehab 11249a0bf528SMauro Carvalho Chehab ret = lg216x_set_ensemble(state, 11259a0bf528SMauro Carvalho Chehab fe->dtv_property_cache.atscmh_rs_frame_ensemble); 11269a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11279a0bf528SMauro Carvalho Chehab goto fail; 11289a0bf528SMauro Carvalho Chehab 11299a0bf528SMauro Carvalho Chehab ret = lg216x_initialize(state); 11309a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11319a0bf528SMauro Carvalho Chehab goto fail; 11329a0bf528SMauro Carvalho Chehab 11339a0bf528SMauro Carvalho Chehab ret = lg216x_enable_fic(state, 1); 11349a0bf528SMauro Carvalho Chehab lg_fail(ret); 11359a0bf528SMauro Carvalho Chehab 11367e3e68bcSMauro Carvalho Chehab lg216x_get_frontend(fe, c); 11379a0bf528SMauro Carvalho Chehab fail: 11389a0bf528SMauro Carvalho Chehab return ret; 11399a0bf528SMauro Carvalho Chehab } 11409a0bf528SMauro Carvalho Chehab 11419a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 11429a0bf528SMauro Carvalho Chehab 11439a0bf528SMauro Carvalho Chehab static int lg2160_read_lock_status(struct lg216x_state *state, 11449a0bf528SMauro Carvalho Chehab int *acq_lock, int *sync_lock) 11459a0bf528SMauro Carvalho Chehab { 11469a0bf528SMauro Carvalho Chehab u8 val; 11479a0bf528SMauro Carvalho Chehab int ret; 11489a0bf528SMauro Carvalho Chehab 11499a0bf528SMauro Carvalho Chehab *acq_lock = 0; 11509a0bf528SMauro Carvalho Chehab *sync_lock = 0; 11519a0bf528SMauro Carvalho Chehab 11529a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x011b, &val); 11539a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11549a0bf528SMauro Carvalho Chehab goto fail; 11559a0bf528SMauro Carvalho Chehab 11569a0bf528SMauro Carvalho Chehab *sync_lock = (val & 0x20) ? 0 : 1; 11579a0bf528SMauro Carvalho Chehab *acq_lock = (val & 0x40) ? 0 : 1; 11589a0bf528SMauro Carvalho Chehab fail: 11599a0bf528SMauro Carvalho Chehab return ret; 11609a0bf528SMauro Carvalho Chehab } 11619a0bf528SMauro Carvalho Chehab 11629a0bf528SMauro Carvalho Chehab #ifdef USE_LG2161_LOCK_BITS 11639a0bf528SMauro Carvalho Chehab static int lg2161_read_lock_status(struct lg216x_state *state, 11649a0bf528SMauro Carvalho Chehab int *acq_lock, int *sync_lock) 11659a0bf528SMauro Carvalho Chehab { 11669a0bf528SMauro Carvalho Chehab u8 val; 11679a0bf528SMauro Carvalho Chehab int ret; 11689a0bf528SMauro Carvalho Chehab 11699a0bf528SMauro Carvalho Chehab *acq_lock = 0; 11709a0bf528SMauro Carvalho Chehab *sync_lock = 0; 11719a0bf528SMauro Carvalho Chehab 11729a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0304, &val); 11739a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11749a0bf528SMauro Carvalho Chehab goto fail; 11759a0bf528SMauro Carvalho Chehab 11769a0bf528SMauro Carvalho Chehab *sync_lock = (val & 0x80) ? 0 : 1; 11779a0bf528SMauro Carvalho Chehab 11789a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x011b, &val); 11799a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 11809a0bf528SMauro Carvalho Chehab goto fail; 11819a0bf528SMauro Carvalho Chehab 11829a0bf528SMauro Carvalho Chehab *acq_lock = (val & 0x40) ? 0 : 1; 11839a0bf528SMauro Carvalho Chehab fail: 11849a0bf528SMauro Carvalho Chehab return ret; 11859a0bf528SMauro Carvalho Chehab } 11869a0bf528SMauro Carvalho Chehab #endif 11879a0bf528SMauro Carvalho Chehab 11889a0bf528SMauro Carvalho Chehab static int lg216x_read_lock_status(struct lg216x_state *state, 11899a0bf528SMauro Carvalho Chehab int *acq_lock, int *sync_lock) 11909a0bf528SMauro Carvalho Chehab { 11919a0bf528SMauro Carvalho Chehab #ifdef USE_LG2161_LOCK_BITS 11929a0bf528SMauro Carvalho Chehab int ret; 11939a0bf528SMauro Carvalho Chehab switch (state->cfg->lg_chip) { 11949a0bf528SMauro Carvalho Chehab case LG2160: 11959a0bf528SMauro Carvalho Chehab ret = lg2160_read_lock_status(state, acq_lock, sync_lock); 11969a0bf528SMauro Carvalho Chehab break; 11979a0bf528SMauro Carvalho Chehab case LG2161: 11989a0bf528SMauro Carvalho Chehab ret = lg2161_read_lock_status(state, acq_lock, sync_lock); 11999a0bf528SMauro Carvalho Chehab break; 12009a0bf528SMauro Carvalho Chehab default: 12019a0bf528SMauro Carvalho Chehab ret = -EINVAL; 12029a0bf528SMauro Carvalho Chehab break; 12039a0bf528SMauro Carvalho Chehab } 12049a0bf528SMauro Carvalho Chehab return ret; 12059a0bf528SMauro Carvalho Chehab #else 12069a0bf528SMauro Carvalho Chehab return lg2160_read_lock_status(state, acq_lock, sync_lock); 12079a0bf528SMauro Carvalho Chehab #endif 12089a0bf528SMauro Carvalho Chehab } 12099a0bf528SMauro Carvalho Chehab 12100df289a2SMauro Carvalho Chehab static int lg216x_read_status(struct dvb_frontend *fe, enum fe_status *status) 12119a0bf528SMauro Carvalho Chehab { 12129a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 12139a0bf528SMauro Carvalho Chehab int ret, acq_lock, sync_lock; 12149a0bf528SMauro Carvalho Chehab 12159a0bf528SMauro Carvalho Chehab *status = 0; 12169a0bf528SMauro Carvalho Chehab 12179a0bf528SMauro Carvalho Chehab ret = lg216x_read_lock_status(state, &acq_lock, &sync_lock); 12189a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 12199a0bf528SMauro Carvalho Chehab goto fail; 12209a0bf528SMauro Carvalho Chehab 12219a0bf528SMauro Carvalho Chehab lg_dbg("%s%s\n", 12229a0bf528SMauro Carvalho Chehab acq_lock ? "SIGNALEXIST " : "", 12239a0bf528SMauro Carvalho Chehab sync_lock ? "SYNCLOCK" : ""); 12249a0bf528SMauro Carvalho Chehab 12259a0bf528SMauro Carvalho Chehab if (acq_lock) 12269a0bf528SMauro Carvalho Chehab *status |= FE_HAS_SIGNAL; 12279a0bf528SMauro Carvalho Chehab if (sync_lock) 12289a0bf528SMauro Carvalho Chehab *status |= FE_HAS_SYNC; 12299a0bf528SMauro Carvalho Chehab 12309a0bf528SMauro Carvalho Chehab if (*status) 12319a0bf528SMauro Carvalho Chehab *status |= FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK; 12329a0bf528SMauro Carvalho Chehab 12339a0bf528SMauro Carvalho Chehab fail: 12349a0bf528SMauro Carvalho Chehab return ret; 12359a0bf528SMauro Carvalho Chehab } 12369a0bf528SMauro Carvalho Chehab 12379a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 12389a0bf528SMauro Carvalho Chehab 12399a0bf528SMauro Carvalho Chehab static int lg2160_read_snr(struct dvb_frontend *fe, u16 *snr) 12409a0bf528SMauro Carvalho Chehab { 12419a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 12429a0bf528SMauro Carvalho Chehab u8 snr1, snr2; 12439a0bf528SMauro Carvalho Chehab int ret; 12449a0bf528SMauro Carvalho Chehab 12459a0bf528SMauro Carvalho Chehab *snr = 0; 12469a0bf528SMauro Carvalho Chehab 12479a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0202, &snr1); 12489a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 12499a0bf528SMauro Carvalho Chehab goto fail; 12509a0bf528SMauro Carvalho Chehab 12519a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0203, &snr2); 12529a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 12539a0bf528SMauro Carvalho Chehab goto fail; 12549a0bf528SMauro Carvalho Chehab 12559a0bf528SMauro Carvalho Chehab if ((snr1 == 0xba) || (snr2 == 0xdf)) 12569a0bf528SMauro Carvalho Chehab *snr = 0; 12579a0bf528SMauro Carvalho Chehab else 12589a0bf528SMauro Carvalho Chehab #if 1 12599a0bf528SMauro Carvalho Chehab *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 >> 4); 12609a0bf528SMauro Carvalho Chehab #else /* BCD */ 12619a0bf528SMauro Carvalho Chehab *snr = (snr2 | (snr1 << 8)); 12629a0bf528SMauro Carvalho Chehab #endif 12639a0bf528SMauro Carvalho Chehab fail: 12649a0bf528SMauro Carvalho Chehab return ret; 12659a0bf528SMauro Carvalho Chehab } 12669a0bf528SMauro Carvalho Chehab 12679a0bf528SMauro Carvalho Chehab static int lg2161_read_snr(struct dvb_frontend *fe, u16 *snr) 12689a0bf528SMauro Carvalho Chehab { 12699a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 12709a0bf528SMauro Carvalho Chehab u8 snr1, snr2; 12719a0bf528SMauro Carvalho Chehab int ret; 12729a0bf528SMauro Carvalho Chehab 12739a0bf528SMauro Carvalho Chehab *snr = 0; 12749a0bf528SMauro Carvalho Chehab 12759a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0302, &snr1); 12769a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 12779a0bf528SMauro Carvalho Chehab goto fail; 12789a0bf528SMauro Carvalho Chehab 12799a0bf528SMauro Carvalho Chehab ret = lg216x_read_reg(state, 0x0303, &snr2); 12809a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 12819a0bf528SMauro Carvalho Chehab goto fail; 12829a0bf528SMauro Carvalho Chehab 12839a0bf528SMauro Carvalho Chehab if ((snr1 == 0xba) || (snr2 == 0xfd)) 12849a0bf528SMauro Carvalho Chehab *snr = 0; 12859a0bf528SMauro Carvalho Chehab else 12869a0bf528SMauro Carvalho Chehab 12879a0bf528SMauro Carvalho Chehab *snr = ((snr1 >> 4) * 100) + ((snr1 & 0x0f) * 10) + (snr2 & 0x0f); 12889a0bf528SMauro Carvalho Chehab fail: 12899a0bf528SMauro Carvalho Chehab return ret; 12909a0bf528SMauro Carvalho Chehab } 12919a0bf528SMauro Carvalho Chehab 12929a0bf528SMauro Carvalho Chehab static int lg216x_read_signal_strength(struct dvb_frontend *fe, 12939a0bf528SMauro Carvalho Chehab u16 *strength) 12949a0bf528SMauro Carvalho Chehab { 12959a0bf528SMauro Carvalho Chehab #if 0 12969a0bf528SMauro Carvalho Chehab /* borrowed from lgdt330x.c 12979a0bf528SMauro Carvalho Chehab * 12989a0bf528SMauro Carvalho Chehab * Calculate strength from SNR up to 35dB 12999a0bf528SMauro Carvalho Chehab * Even though the SNR can go higher than 35dB, 13009a0bf528SMauro Carvalho Chehab * there is some comfort factor in having a range of 13019a0bf528SMauro Carvalho Chehab * strong signals that can show at 100% 13029a0bf528SMauro Carvalho Chehab */ 13039a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 13049a0bf528SMauro Carvalho Chehab u16 snr; 13059a0bf528SMauro Carvalho Chehab int ret; 13069a0bf528SMauro Carvalho Chehab #endif 13079a0bf528SMauro Carvalho Chehab *strength = 0; 13089a0bf528SMauro Carvalho Chehab #if 0 13099a0bf528SMauro Carvalho Chehab ret = fe->ops.read_snr(fe, &snr); 13109a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 13119a0bf528SMauro Carvalho Chehab goto fail; 13129a0bf528SMauro Carvalho Chehab /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ 13139a0bf528SMauro Carvalho Chehab /* scale the range 0 - 35*2^24 into 0 - 65535 */ 13149a0bf528SMauro Carvalho Chehab if (state->snr >= 8960 * 0x10000) 13159a0bf528SMauro Carvalho Chehab *strength = 0xffff; 13169a0bf528SMauro Carvalho Chehab else 13179a0bf528SMauro Carvalho Chehab *strength = state->snr / 8960; 13189a0bf528SMauro Carvalho Chehab fail: 13199a0bf528SMauro Carvalho Chehab return ret; 13209a0bf528SMauro Carvalho Chehab #else 13219a0bf528SMauro Carvalho Chehab return 0; 13229a0bf528SMauro Carvalho Chehab #endif 13239a0bf528SMauro Carvalho Chehab } 13249a0bf528SMauro Carvalho Chehab 13259a0bf528SMauro Carvalho Chehab /* ------------------------------------------------------------------------ */ 13269a0bf528SMauro Carvalho Chehab 13279a0bf528SMauro Carvalho Chehab static int lg216x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) 13289a0bf528SMauro Carvalho Chehab { 13299a0bf528SMauro Carvalho Chehab #if 0 13309a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 13319a0bf528SMauro Carvalho Chehab int ret; 13329a0bf528SMauro Carvalho Chehab 13339a0bf528SMauro Carvalho Chehab ret = lg216x_read_rs_err_count(state, 13349a0bf528SMauro Carvalho Chehab &fe->dtv_property_cache.atscmh_rs_err); 13359a0bf528SMauro Carvalho Chehab if (lg_fail(ret)) 13369a0bf528SMauro Carvalho Chehab goto fail; 13379a0bf528SMauro Carvalho Chehab 13389a0bf528SMauro Carvalho Chehab *ucblocks = fe->dtv_property_cache.atscmh_rs_err; 13399a0bf528SMauro Carvalho Chehab fail: 13409a0bf528SMauro Carvalho Chehab #else 13419a0bf528SMauro Carvalho Chehab *ucblocks = 0; 13429a0bf528SMauro Carvalho Chehab #endif 13439a0bf528SMauro Carvalho Chehab return 0; 13449a0bf528SMauro Carvalho Chehab } 13459a0bf528SMauro Carvalho Chehab 13469a0bf528SMauro Carvalho Chehab static int lg216x_get_tune_settings(struct dvb_frontend *fe, 13479a0bf528SMauro Carvalho Chehab struct dvb_frontend_tune_settings 13489a0bf528SMauro Carvalho Chehab *fe_tune_settings) 13499a0bf528SMauro Carvalho Chehab { 13509a0bf528SMauro Carvalho Chehab fe_tune_settings->min_delay_ms = 500; 13519a0bf528SMauro Carvalho Chehab lg_dbg("\n"); 13529a0bf528SMauro Carvalho Chehab return 0; 13539a0bf528SMauro Carvalho Chehab } 13549a0bf528SMauro Carvalho Chehab 13559a0bf528SMauro Carvalho Chehab static void lg216x_release(struct dvb_frontend *fe) 13569a0bf528SMauro Carvalho Chehab { 13579a0bf528SMauro Carvalho Chehab struct lg216x_state *state = fe->demodulator_priv; 13589a0bf528SMauro Carvalho Chehab lg_dbg("\n"); 13599a0bf528SMauro Carvalho Chehab kfree(state); 13609a0bf528SMauro Carvalho Chehab } 13619a0bf528SMauro Carvalho Chehab 13629a0bf528SMauro Carvalho Chehab static struct dvb_frontend_ops lg2160_ops = { 13639a0bf528SMauro Carvalho Chehab .delsys = { SYS_ATSCMH }, 13649a0bf528SMauro Carvalho Chehab .info = { 13659a0bf528SMauro Carvalho Chehab .name = "LG Electronics LG2160 ATSC/MH Frontend", 13669a0bf528SMauro Carvalho Chehab .frequency_min = 54000000, 13679a0bf528SMauro Carvalho Chehab .frequency_max = 858000000, 13689a0bf528SMauro Carvalho Chehab .frequency_stepsize = 62500, 13699a0bf528SMauro Carvalho Chehab }, 13709a0bf528SMauro Carvalho Chehab .i2c_gate_ctrl = lg216x_i2c_gate_ctrl, 13719a0bf528SMauro Carvalho Chehab #if 0 13729a0bf528SMauro Carvalho Chehab .init = lg216x_init, 13739a0bf528SMauro Carvalho Chehab .sleep = lg216x_sleep, 13749a0bf528SMauro Carvalho Chehab #endif 13759a0bf528SMauro Carvalho Chehab .get_property = lg216x_get_property, 13769a0bf528SMauro Carvalho Chehab 13779a0bf528SMauro Carvalho Chehab .set_frontend = lg2160_set_frontend, 13789a0bf528SMauro Carvalho Chehab .get_frontend = lg216x_get_frontend, 13799a0bf528SMauro Carvalho Chehab .get_tune_settings = lg216x_get_tune_settings, 13809a0bf528SMauro Carvalho Chehab .read_status = lg216x_read_status, 13819a0bf528SMauro Carvalho Chehab #if 0 13829a0bf528SMauro Carvalho Chehab .read_ber = lg216x_read_ber, 13839a0bf528SMauro Carvalho Chehab #endif 13849a0bf528SMauro Carvalho Chehab .read_signal_strength = lg216x_read_signal_strength, 13859a0bf528SMauro Carvalho Chehab .read_snr = lg2160_read_snr, 13869a0bf528SMauro Carvalho Chehab .read_ucblocks = lg216x_read_ucblocks, 13879a0bf528SMauro Carvalho Chehab .release = lg216x_release, 13889a0bf528SMauro Carvalho Chehab }; 13899a0bf528SMauro Carvalho Chehab 13909a0bf528SMauro Carvalho Chehab static struct dvb_frontend_ops lg2161_ops = { 13919a0bf528SMauro Carvalho Chehab .delsys = { SYS_ATSCMH }, 13929a0bf528SMauro Carvalho Chehab .info = { 13939a0bf528SMauro Carvalho Chehab .name = "LG Electronics LG2161 ATSC/MH Frontend", 13949a0bf528SMauro Carvalho Chehab .frequency_min = 54000000, 13959a0bf528SMauro Carvalho Chehab .frequency_max = 858000000, 13969a0bf528SMauro Carvalho Chehab .frequency_stepsize = 62500, 13979a0bf528SMauro Carvalho Chehab }, 13989a0bf528SMauro Carvalho Chehab .i2c_gate_ctrl = lg216x_i2c_gate_ctrl, 13999a0bf528SMauro Carvalho Chehab #if 0 14009a0bf528SMauro Carvalho Chehab .init = lg216x_init, 14019a0bf528SMauro Carvalho Chehab .sleep = lg216x_sleep, 14029a0bf528SMauro Carvalho Chehab #endif 14039a0bf528SMauro Carvalho Chehab .get_property = lg216x_get_property, 14049a0bf528SMauro Carvalho Chehab 14059a0bf528SMauro Carvalho Chehab .set_frontend = lg2160_set_frontend, 14069a0bf528SMauro Carvalho Chehab .get_frontend = lg216x_get_frontend, 14079a0bf528SMauro Carvalho Chehab .get_tune_settings = lg216x_get_tune_settings, 14089a0bf528SMauro Carvalho Chehab .read_status = lg216x_read_status, 14099a0bf528SMauro Carvalho Chehab #if 0 14109a0bf528SMauro Carvalho Chehab .read_ber = lg216x_read_ber, 14119a0bf528SMauro Carvalho Chehab #endif 14129a0bf528SMauro Carvalho Chehab .read_signal_strength = lg216x_read_signal_strength, 14139a0bf528SMauro Carvalho Chehab .read_snr = lg2161_read_snr, 14149a0bf528SMauro Carvalho Chehab .read_ucblocks = lg216x_read_ucblocks, 14159a0bf528SMauro Carvalho Chehab .release = lg216x_release, 14169a0bf528SMauro Carvalho Chehab }; 14179a0bf528SMauro Carvalho Chehab 14189a0bf528SMauro Carvalho Chehab struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, 14199a0bf528SMauro Carvalho Chehab struct i2c_adapter *i2c_adap) 14209a0bf528SMauro Carvalho Chehab { 14219a0bf528SMauro Carvalho Chehab struct lg216x_state *state = NULL; 14229a0bf528SMauro Carvalho Chehab 14239a0bf528SMauro Carvalho Chehab lg_dbg("(%d-%04x)\n", 14249a0bf528SMauro Carvalho Chehab i2c_adap ? i2c_adapter_id(i2c_adap) : 0, 14259a0bf528SMauro Carvalho Chehab config ? config->i2c_addr : 0); 14269a0bf528SMauro Carvalho Chehab 14279a0bf528SMauro Carvalho Chehab state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL); 14281a5d2da1SPeter Senna Tschudin if (!state) 14291a5d2da1SPeter Senna Tschudin return NULL; 14309a0bf528SMauro Carvalho Chehab 14319a0bf528SMauro Carvalho Chehab state->cfg = config; 14329a0bf528SMauro Carvalho Chehab state->i2c_adap = i2c_adap; 14339a0bf528SMauro Carvalho Chehab state->fic_ver = 0xff; 14349a0bf528SMauro Carvalho Chehab state->parade_id = 0xff; 14359a0bf528SMauro Carvalho Chehab 14369a0bf528SMauro Carvalho Chehab switch (config->lg_chip) { 14379a0bf528SMauro Carvalho Chehab default: 14389a0bf528SMauro Carvalho Chehab lg_warn("invalid chip requested, defaulting to LG2160"); 14399a0bf528SMauro Carvalho Chehab /* fall-thru */ 14409a0bf528SMauro Carvalho Chehab case LG2160: 14419a0bf528SMauro Carvalho Chehab memcpy(&state->frontend.ops, &lg2160_ops, 14429a0bf528SMauro Carvalho Chehab sizeof(struct dvb_frontend_ops)); 14439a0bf528SMauro Carvalho Chehab break; 14449a0bf528SMauro Carvalho Chehab case LG2161: 14459a0bf528SMauro Carvalho Chehab memcpy(&state->frontend.ops, &lg2161_ops, 14469a0bf528SMauro Carvalho Chehab sizeof(struct dvb_frontend_ops)); 14479a0bf528SMauro Carvalho Chehab break; 14489a0bf528SMauro Carvalho Chehab } 14499a0bf528SMauro Carvalho Chehab 14509a0bf528SMauro Carvalho Chehab state->frontend.demodulator_priv = state; 14519a0bf528SMauro Carvalho Chehab state->current_frequency = -1; 14529a0bf528SMauro Carvalho Chehab /* parade 1 by default */ 14539a0bf528SMauro Carvalho Chehab state->frontend.dtv_property_cache.atscmh_parade_id = 1; 14549a0bf528SMauro Carvalho Chehab 14559a0bf528SMauro Carvalho Chehab return &state->frontend; 14569a0bf528SMauro Carvalho Chehab } 14579a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(lg2160_attach); 14589a0bf528SMauro Carvalho Chehab 14599a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver"); 14609a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 14619a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL"); 14629a0bf528SMauro Carvalho Chehab MODULE_VERSION("0.3"); 1463