1121 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * helene.c4 *5 * Sony HELENE DVB-S/S2 DVB-T/T2 DVB-C/C2 ISDB-T/S tuner driver (CXD2858ER)6 *7 * Copyright 2012 Sony Corporation8 * Copyright (C) 2014 NetUP Inc.9 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>10 */11 12#include <linux/slab.h>13#include <linux/module.h>14#include <linux/dvb/frontend.h>15#include <linux/types.h>16#include "helene.h"17#include <media/dvb_frontend.h>18 19#define MAX_WRITE_REGSIZE 2020 21enum helene_state {22 STATE_UNKNOWN,23 STATE_SLEEP,24 STATE_ACTIVE25};26 27struct helene_priv {28 u32 frequency;29 u8 i2c_address;30 struct i2c_adapter *i2c;31 enum helene_state state;32 void *set_tuner_data;33 int (*set_tuner)(void *, int);34 enum helene_xtal xtal;35};36 37#define TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system) \38 (((tv_system) != SONY_HELENE_DTV_DVBC_6) && \39 ((tv_system) != SONY_HELENE_DTV_DVBC_8)\40 && ((tv_system) != SONY_HELENE_DTV_DVBC2_6) && \41 ((tv_system) != SONY_HELENE_DTV_DVBC2_8))42 43#define HELENE_AUTO 0xff44#define HELENE_OFFSET(ofs) ((u8)(ofs) & 0x1F)45#define HELENE_BW_6 0x0046#define HELENE_BW_7 0x0147#define HELENE_BW_8 0x0248#define HELENE_BW_1_7 0x0349 50enum helene_tv_system_t {51 SONY_HELENE_TV_SYSTEM_UNKNOWN,52 /* Terrestrial Analog */53 SONY_HELENE_ATV_MN_EIAJ,54 /**< System-M (Japan) (IF: Fp=5.75MHz in default) */55 SONY_HELENE_ATV_MN_SAP,56 /**< System-M (US) (IF: Fp=5.75MHz in default) */57 SONY_HELENE_ATV_MN_A2,58 /**< System-M (Korea) (IF: Fp=5.9MHz in default) */59 SONY_HELENE_ATV_BG,60 /**< System-B/G (IF: Fp=7.3MHz in default) */61 SONY_HELENE_ATV_I,62 /**< System-I (IF: Fp=7.85MHz in default) */63 SONY_HELENE_ATV_DK,64 /**< System-D/K (IF: Fp=7.85MHz in default) */65 SONY_HELENE_ATV_L,66 /**< System-L (IF: Fp=7.85MHz in default) */67 SONY_HELENE_ATV_L_DASH,68 /**< System-L DASH (IF: Fp=2.2MHz in default) */69 /* Terrestrial/Cable Digital */70 SONY_HELENE_DTV_8VSB,71 /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */72 SONY_HELENE_DTV_QAM,73 /**< US QAM (IF: Fc=3.7MHz in default) */74 SONY_HELENE_DTV_ISDBT_6,75 /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */76 SONY_HELENE_DTV_ISDBT_7,77 /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */78 SONY_HELENE_DTV_ISDBT_8,79 /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */80 SONY_HELENE_DTV_DVBT_5,81 /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */82 SONY_HELENE_DTV_DVBT_6,83 /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */84 SONY_HELENE_DTV_DVBT_7,85 /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */86 SONY_HELENE_DTV_DVBT_8,87 /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */88 SONY_HELENE_DTV_DVBT2_1_7,89 /**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */90 SONY_HELENE_DTV_DVBT2_5,91 /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */92 SONY_HELENE_DTV_DVBT2_6,93 /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */94 SONY_HELENE_DTV_DVBT2_7,95 /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */96 SONY_HELENE_DTV_DVBT2_8,97 /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */98 SONY_HELENE_DTV_DVBC_6,99 /**< DVB-C 6MHzBW (IF: Fc=3.7MHz in default) */100 SONY_HELENE_DTV_DVBC_8,101 /**< DVB-C 8MHzBW (IF: Fc=4.9MHz in default) */102 SONY_HELENE_DTV_DVBC2_6,103 /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */104 SONY_HELENE_DTV_DVBC2_8,105 /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */106 SONY_HELENE_DTV_DTMB,107 /**< DTMB (IF: Fc=5.1MHz in default) */108 /* Satellite */109 SONY_HELENE_STV_ISDBS,110 /**< ISDB-S */111 SONY_HELENE_STV_DVBS,112 /**< DVB-S */113 SONY_HELENE_STV_DVBS2,114 /**< DVB-S2 */115 116 SONY_HELENE_ATV_MIN = SONY_HELENE_ATV_MN_EIAJ,117 /**< Minimum analog terrestrial system */118 SONY_HELENE_ATV_MAX = SONY_HELENE_ATV_L_DASH,119 /**< Maximum analog terrestrial system */120 SONY_HELENE_DTV_MIN = SONY_HELENE_DTV_8VSB,121 /**< Minimum digital terrestrial system */122 SONY_HELENE_DTV_MAX = SONY_HELENE_DTV_DTMB,123 /**< Maximum digital terrestrial system */124 SONY_HELENE_TERR_TV_SYSTEM_NUM,125 /**< Number of supported terrestrial broadcasting system */126 SONY_HELENE_STV_MIN = SONY_HELENE_STV_ISDBS,127 /**< Minimum satellite system */128 SONY_HELENE_STV_MAX = SONY_HELENE_STV_DVBS2129 /**< Maximum satellite system */130};131 132struct helene_terr_adjust_param_t {133 /* < Addr:0x69 Bit[6:4] : RFVGA gain.134 * 0xFF means Auto. (RF_GAIN_SEL = 1)135 */136 uint8_t RF_GAIN;137 /* < Addr:0x69 Bit[3:0] : IF_BPF gain.138 */139 uint8_t IF_BPF_GC;140 /* < Addr:0x6B Bit[3:0] : RF overload141 * RF input detect level. (FRF <= 172MHz)142 */143 uint8_t RFOVLD_DET_LV1_VL;144 /* < Addr:0x6B Bit[3:0] : RF overload145 * RF input detect level. (172MHz < FRF <= 464MHz)146 */147 uint8_t RFOVLD_DET_LV1_VH;148 /* < Addr:0x6B Bit[3:0] : RF overload149 * RF input detect level. (FRF > 464MHz)150 */151 uint8_t RFOVLD_DET_LV1_U;152 /* < Addr:0x6C Bit[2:0] :153 * Internal RFAGC detect level. (FRF <= 172MHz)154 */155 uint8_t IFOVLD_DET_LV_VL;156 /* < Addr:0x6C Bit[2:0] :157 * Internal RFAGC detect level. (172MHz < FRF <= 464MHz)158 */159 uint8_t IFOVLD_DET_LV_VH;160 /* < Addr:0x6C Bit[2:0] :161 * Internal RFAGC detect level. (FRF > 464MHz)162 */163 uint8_t IFOVLD_DET_LV_U;164 /* < Addr:0x6D Bit[5:4] :165 * IF filter center offset.166 */167 uint8_t IF_BPF_F0;168 /* < Addr:0x6D Bit[1:0] :169 * 6MHzBW(0x00) or 7MHzBW(0x01)170 * or 8MHzBW(0x02) or 1.7MHzBW(0x03)171 */172 uint8_t BW;173 /* < Addr:0x6E Bit[4:0] :174 * 5bit signed. IF offset (kHz) = FIF_OFFSET x 50175 */176 uint8_t FIF_OFFSET;177 /* < Addr:0x6F Bit[4:0] :178 * 5bit signed. BW offset (kHz) =179 * BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW)180 */181 uint8_t BW_OFFSET;182 /* < Addr:0x9C Bit[0] :183 * Local polarity. (0: Upper Local, 1: Lower Local)184 */185 uint8_t IS_LOWERLOCAL;186};187 188static const struct helene_terr_adjust_param_t189terr_params[SONY_HELENE_TERR_TV_SYSTEM_NUM] = {190 /*< SONY_HELENE_TV_SYSTEM_UNKNOWN */191 {HELENE_AUTO, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,192 HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(0), 0x00},193 /* Analog */194 /**< SONY_HELENE_ATV_MN_EIAJ (System-M (Japan)) */195 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,196 HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(1), 0x00},197 /**< SONY_HELENE_ATV_MN_SAP (System-M (US)) */198 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,199 HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(1), 0x00},200 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,201 HELENE_BW_6, HELENE_OFFSET(3), HELENE_OFFSET(1), 0x00},202 /**< SONY_HELENE_ATV_MN_A2 (System-M (Korea)) */203 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,204 HELENE_BW_7, HELENE_OFFSET(11), HELENE_OFFSET(5), 0x00},205 /**< SONY_HELENE_ATV_BG (System-B/G) */206 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,207 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00},208 /**< SONY_HELENE_ATV_I (System-I) */209 {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,210 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00},211 /**< SONY_HELENE_ATV_DK (System-D/K) */212 {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00,213 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00},214 /**< SONY_HELENE_ATV_L (System-L) */215 {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00,216 HELENE_BW_8, HELENE_OFFSET(-1), HELENE_OFFSET(4), 0x00},217 /**< SONY_HELENE_ATV_L_DASH (System-L DASH) */218 /* Digital */219 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x03, 0x03, 0x03, 0x00,220 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00},221 /**< SONY_HELENE_DTV_8VSB (ATSC 8VSB) */222 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,223 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00},224 /**< SONY_HELENE_DTV_QAM (US QAM) */225 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,226 HELENE_BW_6, HELENE_OFFSET(-9), HELENE_OFFSET(-5), 0x00},227 /**< SONY_HELENE_DTV_ISDBT_6 (ISDB-T 6MHzBW) */228 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,229 HELENE_BW_7, HELENE_OFFSET(-7), HELENE_OFFSET(-6), 0x00},230 /**< SONY_HELENE_DTV_ISDBT_7 (ISDB-T 7MHzBW) */231 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,232 HELENE_BW_8, HELENE_OFFSET(-5), HELENE_OFFSET(-7), 0x00},233 /**< SONY_HELENE_DTV_ISDBT_8 (ISDB-T 8MHzBW) */234 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,235 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},236 /**< SONY_HELENE_DTV_DVBT_5 (DVB-T 5MHzBW) */237 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,238 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},239 /**< SONY_HELENE_DTV_DVBT_6 (DVB-T 6MHzBW) */240 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,241 HELENE_BW_7, HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00},242 /**< SONY_HELENE_DTV_DVBT_7 (DVB-T 7MHzBW) */243 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,244 HELENE_BW_8, HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00},245 /**< SONY_HELENE_DTV_DVBT_8 (DVB-T 8MHzBW) */246 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,247 HELENE_BW_1_7, HELENE_OFFSET(-10), HELENE_OFFSET(-10), 0x00},248 /**< SONY_HELENE_DTV_DVBT2_1_7 (DVB-T2 1.7MHzBW) */249 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,250 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},251 /**< SONY_HELENE_DTV_DVBT2_5 (DVB-T2 5MHzBW) */252 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,253 HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},254 /**< SONY_HELENE_DTV_DVBT2_6 (DVB-T2 6MHzBW) */255 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,256 HELENE_BW_7, HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00},257 /**< SONY_HELENE_DTV_DVBT2_7 (DVB-T2 7MHzBW) */258 {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,259 HELENE_BW_8, HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00},260 /**< SONY_HELENE_DTV_DVBT2_8 (DVB-T2 8MHzBW) */261 {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00,262 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-4), 0x00},263 /**< SONY_HELENE_DTV_DVBC_6 (DVB-C 6MHzBW) */264 {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00,265 HELENE_BW_8, HELENE_OFFSET(-2), HELENE_OFFSET(-3), 0x00},266 /**< SONY_HELENE_DTV_DVBC_8 (DVB-C 8MHzBW) */267 {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00,268 HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-2), 0x00},269 /**< SONY_HELENE_DTV_DVBC2_6 (DVB-C2 6MHzBW) */270 {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00,271 HELENE_BW_8, HELENE_OFFSET(-2), HELENE_OFFSET(0), 0x00},272 /**< SONY_HELENE_DTV_DVBC2_8 (DVB-C2 8MHzBW) */273 {HELENE_AUTO, 0x04, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,274 HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(1), 0x00}275 /**< SONY_HELENE_DTV_DTMB (DTMB) */276};277 278static void helene_i2c_debug(struct helene_priv *priv,279 u8 reg, u8 write, const u8 *data, u32 len)280{281 dev_dbg(&priv->i2c->dev, "helene: I2C %s reg 0x%02x size %d\n",282 (write == 0 ? "read" : "write"), reg, len);283 print_hex_dump_bytes("helene: I2C data: ",284 DUMP_PREFIX_OFFSET, data, len);285}286 287static int helene_write_regs(struct helene_priv *priv,288 u8 reg, const u8 *data, u32 len)289{290 int ret;291 u8 buf[MAX_WRITE_REGSIZE + 1];292 struct i2c_msg msg[1] = {293 {294 .addr = priv->i2c_address,295 .flags = 0,296 .len = len + 1,297 .buf = buf,298 }299 };300 301 if (len + 1 > sizeof(buf)) {302 dev_warn(&priv->i2c->dev,303 "wr reg=%04x: len=%d vs %zu is too big!\n",304 reg, len + 1, sizeof(buf));305 return -E2BIG;306 }307 308 helene_i2c_debug(priv, reg, 1, data, len);309 buf[0] = reg;310 memcpy(&buf[1], data, len);311 ret = i2c_transfer(priv->i2c, msg, 1);312 if (ret >= 0 && ret != 1)313 ret = -EREMOTEIO;314 if (ret < 0) {315 dev_warn(&priv->i2c->dev,316 "%s: i2c wr failed=%d reg=%02x len=%d\n",317 KBUILD_MODNAME, ret, reg, len);318 return ret;319 }320 return 0;321}322 323static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)324{325 u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */326 327 return helene_write_regs(priv, reg, &tmp, 1);328}329 330static int helene_read_regs(struct helene_priv *priv,331 u8 reg, u8 *val, u32 len)332{333 int ret;334 struct i2c_msg msg[2] = {335 {336 .addr = priv->i2c_address,337 .flags = 0,338 .len = 1,339 .buf = ®,340 }, {341 .addr = priv->i2c_address,342 .flags = I2C_M_RD,343 .len = len,344 .buf = val,345 }346 };347 348 ret = i2c_transfer(priv->i2c, &msg[0], 1);349 if (ret >= 0 && ret != 1)350 ret = -EREMOTEIO;351 if (ret < 0) {352 dev_warn(&priv->i2c->dev,353 "%s: I2C rw failed=%d addr=%02x reg=%02x\n",354 KBUILD_MODNAME, ret, priv->i2c_address, reg);355 return ret;356 }357 ret = i2c_transfer(priv->i2c, &msg[1], 1);358 if (ret >= 0 && ret != 1)359 ret = -EREMOTEIO;360 if (ret < 0) {361 dev_warn(&priv->i2c->dev,362 "%s: i2c rd failed=%d addr=%02x reg=%02x\n",363 KBUILD_MODNAME, ret, priv->i2c_address, reg);364 return ret;365 }366 helene_i2c_debug(priv, reg, 0, val, len);367 return 0;368}369 370static int helene_read_reg(struct helene_priv *priv, u8 reg, u8 *val)371{372 return helene_read_regs(priv, reg, val, 1);373}374 375static int helene_set_reg_bits(struct helene_priv *priv,376 u8 reg, u8 data, u8 mask)377{378 int res;379 u8 rdata;380 381 if (mask != 0xff) {382 res = helene_read_reg(priv, reg, &rdata);383 if (res != 0)384 return res;385 data = ((data & mask) | (rdata & (mask ^ 0xFF)));386 }387 return helene_write_reg(priv, reg, data);388}389 390static int helene_enter_power_save(struct helene_priv *priv)391{392 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);393 if (priv->state == STATE_SLEEP)394 return 0;395 396 /* Standby setting for CPU */397 helene_write_reg(priv, 0x88, 0x0);398 399 /* Standby setting for internal logic block */400 helene_write_reg(priv, 0x87, 0xC0);401 402 priv->state = STATE_SLEEP;403 return 0;404}405 406static int helene_leave_power_save(struct helene_priv *priv)407{408 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);409 if (priv->state == STATE_ACTIVE)410 return 0;411 412 /* Standby setting for internal logic block */413 helene_write_reg(priv, 0x87, 0xC4);414 415 /* Standby setting for CPU */416 helene_write_reg(priv, 0x88, 0x40);417 418 priv->state = STATE_ACTIVE;419 return 0;420}421 422static int helene_init(struct dvb_frontend *fe)423{424 struct helene_priv *priv = fe->tuner_priv;425 426 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);427 return helene_leave_power_save(priv);428}429 430static void helene_release(struct dvb_frontend *fe)431{432 struct helene_priv *priv = fe->tuner_priv;433 434 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);435 kfree(fe->tuner_priv);436 fe->tuner_priv = NULL;437}438 439static int helene_sleep(struct dvb_frontend *fe)440{441 struct helene_priv *priv = fe->tuner_priv;442 443 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);444 helene_enter_power_save(priv);445 return 0;446}447 448static enum helene_tv_system_t helene_get_tv_system(struct dvb_frontend *fe)449{450 enum helene_tv_system_t system = SONY_HELENE_TV_SYSTEM_UNKNOWN;451 struct dtv_frontend_properties *p = &fe->dtv_property_cache;452 struct helene_priv *priv = fe->tuner_priv;453 454 if (p->delivery_system == SYS_DVBT) {455 if (p->bandwidth_hz <= 5000000)456 system = SONY_HELENE_DTV_DVBT_5;457 else if (p->bandwidth_hz <= 6000000)458 system = SONY_HELENE_DTV_DVBT_6;459 else if (p->bandwidth_hz <= 7000000)460 system = SONY_HELENE_DTV_DVBT_7;461 else if (p->bandwidth_hz <= 8000000)462 system = SONY_HELENE_DTV_DVBT_8;463 else {464 system = SONY_HELENE_DTV_DVBT_8;465 p->bandwidth_hz = 8000000;466 }467 } else if (p->delivery_system == SYS_DVBT2) {468 if (p->bandwidth_hz <= 5000000)469 system = SONY_HELENE_DTV_DVBT2_5;470 else if (p->bandwidth_hz <= 6000000)471 system = SONY_HELENE_DTV_DVBT2_6;472 else if (p->bandwidth_hz <= 7000000)473 system = SONY_HELENE_DTV_DVBT2_7;474 else if (p->bandwidth_hz <= 8000000)475 system = SONY_HELENE_DTV_DVBT2_8;476 else {477 system = SONY_HELENE_DTV_DVBT2_8;478 p->bandwidth_hz = 8000000;479 }480 } else if (p->delivery_system == SYS_DVBS) {481 system = SONY_HELENE_STV_DVBS;482 } else if (p->delivery_system == SYS_DVBS2) {483 system = SONY_HELENE_STV_DVBS2;484 } else if (p->delivery_system == SYS_ISDBS) {485 system = SONY_HELENE_STV_ISDBS;486 } else if (p->delivery_system == SYS_ISDBT) {487 if (p->bandwidth_hz <= 6000000)488 system = SONY_HELENE_DTV_ISDBT_6;489 else if (p->bandwidth_hz <= 7000000)490 system = SONY_HELENE_DTV_ISDBT_7;491 else if (p->bandwidth_hz <= 8000000)492 system = SONY_HELENE_DTV_ISDBT_8;493 else {494 system = SONY_HELENE_DTV_ISDBT_8;495 p->bandwidth_hz = 8000000;496 }497 } else if (p->delivery_system == SYS_DVBC_ANNEX_A) {498 if (p->bandwidth_hz <= 6000000)499 system = SONY_HELENE_DTV_DVBC_6;500 else if (p->bandwidth_hz <= 8000000)501 system = SONY_HELENE_DTV_DVBC_8;502 }503 dev_dbg(&priv->i2c->dev,504 "%s(): HELENE DTV system %d (delsys %d, bandwidth %d)\n",505 __func__, (int)system, p->delivery_system,506 p->bandwidth_hz);507 return system;508}509 510static int helene_set_params_s(struct dvb_frontend *fe)511{512 u8 data[MAX_WRITE_REGSIZE];513 u32 frequency;514 enum helene_tv_system_t tv_system;515 struct dtv_frontend_properties *p = &fe->dtv_property_cache;516 struct helene_priv *priv = fe->tuner_priv;517 int frequencykHz = p->frequency;518 uint32_t frequency4kHz = 0;519 u32 symbol_rate = p->symbol_rate/1000;520 521 dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz sr=%uKsps\n",522 __func__, frequencykHz, symbol_rate);523 tv_system = helene_get_tv_system(fe);524 525 if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) {526 dev_err(&priv->i2c->dev, "%s(): unknown DTV system\n",527 __func__);528 return -EINVAL;529 }530 /* RF switch turn to satellite */531 if (priv->set_tuner)532 priv->set_tuner(priv->set_tuner_data, 0);533 frequency = roundup(p->frequency / 1000, 1);534 535 /* Disable IF signal output */536 helene_write_reg(priv, 0x15, 0x02);537 538 /* RFIN matching in power save (Sat) reset */539 helene_write_reg(priv, 0x43, 0x06);540 541 /* Analog block setting (0x6A, 0x6B) */542 data[0] = 0x00;543 data[1] = 0x00;544 helene_write_regs(priv, 0x6A, data, 2);545 helene_write_reg(priv, 0x75, 0x99);546 helene_write_reg(priv, 0x9D, 0x00);547 548 /* Tuning setting for CPU (0x61) */549 helene_write_reg(priv, 0x61, 0x07);550 551 /* Satellite mode select (0x01) */552 helene_write_reg(priv, 0x01, 0x01);553 554 /* Clock enable for internal logic block, CPU wake-up (0x04, 0x05) */555 data[0] = 0xC4;556 data[1] = 0x40;557 558 switch (priv->xtal) {559 case SONY_HELENE_XTAL_16000:560 data[2] = 0x02;561 break;562 case SONY_HELENE_XTAL_20500:563 data[2] = 0x02;564 break;565 case SONY_HELENE_XTAL_24000:566 data[2] = 0x03;567 break;568 case SONY_HELENE_XTAL_41000:569 data[2] = 0x05;570 break;571 default:572 dev_err(&priv->i2c->dev, "%s(): unknown xtal %d\n",573 __func__, priv->xtal);574 return -EINVAL;575 }576 577 /* Setting for analog block (0x07). LOOPFILTER INTERNAL */578 data[3] = 0x80;579 580 /* Tuning setting for analog block581 * (0x08, 0x09, 0x0A, 0x0B). LOOPFILTER INTERNAL582 */583 if (priv->xtal == SONY_HELENE_XTAL_20500)584 data[4] = 0x58;585 else586 data[4] = 0x70;587 588 data[5] = 0x1E;589 data[6] = 0x02;590 data[7] = 0x24;591 592 /* Enable for analog block (0x0C, 0x0D, 0x0E). SAT LNA ON */593 data[8] = 0x0F;594 data[8] |= 0xE0; /* POWERSAVE_TERR_RF_ACTIVE */595 data[9] = 0x02;596 data[10] = 0x1E;597 598 /* Setting for LPF cutoff frequency (0x0F) */599 switch (tv_system) {600 case SONY_HELENE_STV_ISDBS:601 data[11] = 0x22; /* 22MHz */602 break;603 case SONY_HELENE_STV_DVBS:604 if (symbol_rate <= 4000)605 data[11] = 0x05;606 else if (symbol_rate <= 10000)607 data[11] = (uint8_t)((symbol_rate * 47608 + (40000-1)) / 40000);609 else610 data[11] = (uint8_t)((symbol_rate * 27611 + (40000-1)) / 40000 + 5);612 613 if (data[11] > 36)614 data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */615 break;616 case SONY_HELENE_STV_DVBS2:617 if (symbol_rate <= 4000)618 data[11] = 0x05;619 else if (symbol_rate <= 10000)620 data[11] = (uint8_t)((symbol_rate * 11621 + (10000-1)) / 10000);622 else623 data[11] = (uint8_t)((symbol_rate * 3624 + (5000-1)) / 5000 + 5);625 626 if (data[11] > 36)627 data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */628 break;629 default:630 dev_err(&priv->i2c->dev, "%s(): unknown standard %d\n",631 __func__, tv_system);632 return -EINVAL;633 }634 635 /* RF tuning frequency setting (0x10, 0x11, 0x12) */636 frequency4kHz = (frequencykHz + 2) / 4;637 data[12] = (uint8_t)(frequency4kHz & 0xFF); /* FRF_L */638 data[13] = (uint8_t)((frequency4kHz >> 8) & 0xFF); /* FRF_M */639 /* FRF_H (bit[3:0]) */640 data[14] = (uint8_t)((frequency4kHz >> 16) & 0x0F);641 642 /* Tuning command (0x13) */643 data[15] = 0xFF;644 645 /* Setting for IQOUT_LIMIT (0x14) 0.75Vpp */646 data[16] = 0x00;647 648 /* Enable IQ output (0x15) */649 data[17] = 0x01;650 651 helene_write_regs(priv, 0x04, data, 18);652 653 dev_dbg(&priv->i2c->dev, "%s(): tune done\n",654 __func__);655 656 priv->frequency = frequency;657 return 0;658}659 660static int helene_set_params_t(struct dvb_frontend *fe)661{662 u8 data[MAX_WRITE_REGSIZE];663 u32 frequency;664 enum helene_tv_system_t tv_system;665 struct dtv_frontend_properties *p = &fe->dtv_property_cache;666 struct helene_priv *priv = fe->tuner_priv;667 int frequencykHz = p->frequency / 1000;668 669 dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n",670 __func__, frequencykHz);671 tv_system = helene_get_tv_system(fe);672 673 if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) {674 dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n",675 __func__);676 return -EINVAL;677 }678 if (priv->set_tuner)679 priv->set_tuner(priv->set_tuner_data, 1);680 frequency = roundup(p->frequency / 1000, 25);681 682 /* mode select */683 helene_write_reg(priv, 0x01, 0x00);684 685 /* Disable IF signal output */686 helene_write_reg(priv, 0x74, 0x02);687 688 if (priv->state == STATE_SLEEP)689 helene_leave_power_save(priv);690 691 /* Initial setting for internal analog block (0x91, 0x92) */692 if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||693 (tv_system == SONY_HELENE_DTV_DVBC_8)) {694 data[0] = 0x16;695 data[1] = 0x26;696 } else {697 data[0] = 0x10;698 data[1] = 0x20;699 }700 helene_write_regs(priv, 0x91, data, 2);701 702 /* Setting for analog block */703 if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system))704 data[0] = 0x90;705 else706 data[0] = 0x00;707 708 /* Setting for local polarity (0x9D) */709 data[1] = (uint8_t)(terr_params[tv_system].IS_LOWERLOCAL & 0x01);710 helene_write_regs(priv, 0x9C, data, 2);711 712 /* Enable for analog block */713 data[0] = 0xEE;714 data[1] = 0x02;715 data[2] = 0x1E;716 data[3] = 0x67; /* Tuning setting for CPU */717 718 /* Setting for PLL reference divider for xtal=24MHz */719 if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||720 (tv_system == SONY_HELENE_DTV_DVBC_8))721 data[4] = 0x18;722 else723 data[4] = 0x03;724 725 /* Tuning setting for analog block */726 if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system)) {727 data[5] = 0x38;728 data[6] = 0x1E;729 data[7] = 0x02;730 data[8] = 0x24;731 } else if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||732 (tv_system == SONY_HELENE_DTV_DVBC_8)) {733 data[5] = 0x1C;734 data[6] = 0x78;735 data[7] = 0x08;736 data[8] = 0x1C;737 } else {738 data[5] = 0xB4;739 data[6] = 0x78;740 data[7] = 0x08;741 data[8] = 0x30;742 }743 helene_write_regs(priv, 0x5E, data, 9);744 745 /* LT_AMP_EN should be 0 */746 helene_set_reg_bits(priv, 0x67, 0x0, 0x02);747 748 /* Setting for IFOUT_LIMIT */749 data[0] = 0x00; /* 1.5Vpp */750 751 /* RF_GAIN setting */752 if (terr_params[tv_system].RF_GAIN == HELENE_AUTO)753 data[1] = 0x80; /* RF_GAIN_SEL = 1 */754 else755 data[1] = (uint8_t)((terr_params[tv_system].RF_GAIN756 << 4) & 0x70);757 758 /* IF_BPF_GC setting */759 data[1] |= (uint8_t)(terr_params[tv_system].IF_BPF_GC & 0x0F);760 761 /* Setting for internal RFAGC (0x6A, 0x6B, 0x6C) */762 data[2] = 0x00;763 if (frequencykHz <= 172000) {764 data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VL765 & 0x0F);766 data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VL767 & 0x07);768 } else if (frequencykHz <= 464000) {769 data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VH770 & 0x0F);771 data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VH772 & 0x07);773 } else {774 data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_U775 & 0x0F);776 data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_U777 & 0x07);778 }779 data[4] |= 0x20;780 781 /* Setting for IF frequency and bandwidth */782 783 /* IF filter center frequency offset (IF_BPF_F0) (0x6D) */784 data[5] = (uint8_t)((terr_params[tv_system].IF_BPF_F0 << 4) & 0x30);785 786 /* IF filter band width (BW) (0x6D) */787 data[5] |= (uint8_t)(terr_params[tv_system].BW & 0x03);788 789 /* IF frequency offset value (FIF_OFFSET) (0x6E) */790 data[6] = (uint8_t)(terr_params[tv_system].FIF_OFFSET & 0x1F);791 792 /* IF band width offset value (BW_OFFSET) (0x6F) */793 data[7] = (uint8_t)(terr_params[tv_system].BW_OFFSET & 0x1F);794 795 /* RF tuning frequency setting (0x70, 0x71, 0x72) */796 data[8] = (uint8_t)(frequencykHz & 0xFF); /* FRF_L */797 data[9] = (uint8_t)((frequencykHz >> 8) & 0xFF); /* FRF_M */798 data[10] = (uint8_t)((frequencykHz >> 16)799 & 0x0F); /* FRF_H (bit[3:0]) */800 801 /* Tuning command */802 data[11] = 0xFF;803 804 /* Enable IF output, AGC and IFOUT pin selection (0x74) */805 data[12] = 0x01;806 807 if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||808 (tv_system == SONY_HELENE_DTV_DVBC_8)) {809 data[13] = 0xD9;810 data[14] = 0x0F;811 data[15] = 0x24;812 data[16] = 0x87;813 } else {814 data[13] = 0x99;815 data[14] = 0x00;816 data[15] = 0x24;817 data[16] = 0x87;818 }819 820 helene_write_regs(priv, 0x68, data, 17);821 822 dev_dbg(&priv->i2c->dev, "%s(): tune done\n",823 __func__);824 825 priv->frequency = frequency;826 return 0;827}828 829static int helene_set_params(struct dvb_frontend *fe)830{831 struct dtv_frontend_properties *p = &fe->dtv_property_cache;832 833 if (p->delivery_system == SYS_DVBT ||834 p->delivery_system == SYS_DVBT2 ||835 p->delivery_system == SYS_ISDBT ||836 p->delivery_system == SYS_DVBC_ANNEX_A)837 return helene_set_params_t(fe);838 839 return helene_set_params_s(fe);840}841 842static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency)843{844 struct helene_priv *priv = fe->tuner_priv;845 846 *frequency = priv->frequency * 1000;847 return 0;848}849 850static const struct dvb_tuner_ops helene_tuner_ops_t = {851 .info = {852 .name = "Sony HELENE Ter tuner",853 .frequency_min_hz = 1 * MHz,854 .frequency_max_hz = 1200 * MHz,855 .frequency_step_hz = 25 * kHz,856 },857 .init = helene_init,858 .release = helene_release,859 .sleep = helene_sleep,860 .set_params = helene_set_params_t,861 .get_frequency = helene_get_frequency,862};863 864static const struct dvb_tuner_ops helene_tuner_ops_s = {865 .info = {866 .name = "Sony HELENE Sat tuner",867 .frequency_min_hz = 500 * MHz,868 .frequency_max_hz = 2500 * MHz,869 .frequency_step_hz = 1 * MHz,870 },871 .init = helene_init,872 .release = helene_release,873 .sleep = helene_sleep,874 .set_params = helene_set_params_s,875 .get_frequency = helene_get_frequency,876};877 878static const struct dvb_tuner_ops helene_tuner_ops = {879 .info = {880 .name = "Sony HELENE Sat/Ter tuner",881 .frequency_min_hz = 1 * MHz,882 .frequency_max_hz = 2500 * MHz,883 .frequency_step_hz = 25 * kHz,884 },885 .init = helene_init,886 .release = helene_release,887 .sleep = helene_sleep,888 .set_params = helene_set_params,889 .get_frequency = helene_get_frequency,890};891 892/* power-on tuner893 * call once after reset894 */895static int helene_x_pon(struct helene_priv *priv)896{897 /* RFIN matching in power save (terrestrial) = ACTIVE */898 /* RFIN matching in power save (satellite) = ACTIVE */899 u8 dataT[] = { 0x06, 0x00, 0x02, 0x00 };900 /* SAT_RF_ACTIVE = true, lnaOff = false, terrRfActive = true */901 u8 dataS[] = { 0x05, 0x06 };902 u8 cdata[] = {0x7A, 0x01};903 u8 data[20];904 u8 rdata[2];905 906 /* mode select */907 helene_write_reg(priv, 0x01, 0x00);908 909 helene_write_reg(priv, 0x67, dataT[3]);910 helene_write_reg(priv, 0x43, dataS[1]);911 helene_write_regs(priv, 0x5E, dataT, 3);912 helene_write_reg(priv, 0x0C, dataS[0]);913 914 /* Initial setting for internal logic block */915 helene_write_regs(priv, 0x99, cdata, sizeof(cdata));916 917 /* 0x81 - 0x94 */918 if (priv->xtal == SONY_HELENE_XTAL_16000)919 data[0] = 0x10; /* xtal 16 MHz */920 else921 data[0] = 0x18; /* xtal 24 MHz */922 data[1] = (uint8_t)(0x80 | (0x04 & 0x1F)); /* 4 x 25 = 100uA */923 data[2] = (uint8_t)(0x80 | (0x26 & 0x7F)); /* 38 x 0.25 = 9.5pF */924 data[3] = 0x80; /* REFOUT signal output 500mVpp */925 data[4] = 0x00; /* GPIO settings */926 data[5] = 0x00; /* GPIO settings */927 data[6] = 0xC4; /* Clock enable for internal logic block */928 data[7] = 0x40; /* Start CPU boot-up */929 data[8] = 0x10; /* For burst-write */930 931 /* Setting for internal RFAGC */932 data[9] = 0x00;933 data[10] = 0x45;934 data[11] = 0x75;935 936 data[12] = 0x07; /* Setting for analog block */937 938 /* Initial setting for internal analog block */939 data[13] = 0x1C;940 data[14] = 0x3F;941 data[15] = 0x02;942 data[16] = 0x10;943 data[17] = 0x20;944 data[18] = 0x0A;945 data[19] = 0x00;946 947 helene_write_regs(priv, 0x81, data, sizeof(data));948 949 /* Setting for internal RFAGC */950 helene_write_reg(priv, 0x9B, 0x00);951 952 msleep(20);953 954 /* Check CPU_STT/CPU_ERR */955 helene_read_regs(priv, 0x1A, rdata, sizeof(rdata));956 957 if (rdata[0] != 0x00) {958 dev_err(&priv->i2c->dev,959 "HELENE tuner CPU error 0x%x\n", rdata[0]);960 return -EIO;961 }962 963 /* VCO current setting */964 cdata[0] = 0x90;965 cdata[1] = 0x06;966 helene_write_regs(priv, 0x17, cdata, sizeof(cdata));967 msleep(20);968 helene_read_reg(priv, 0x19, data);969 helene_write_reg(priv, 0x95, (uint8_t)((data[0] >> 4) & 0x0F));970 971 /* Disable IF signal output */972 helene_write_reg(priv, 0x74, 0x02);973 974 /* Standby setting for CPU */975 helene_write_reg(priv, 0x88, 0x00);976 977 /* Standby setting for internal logic block */978 helene_write_reg(priv, 0x87, 0xC0);979 980 /* Load capacitance control setting for crystal oscillator */981 helene_write_reg(priv, 0x80, 0x01);982 983 /* Satellite initial setting */984 cdata[0] = 0x07;985 cdata[1] = 0x00;986 helene_write_regs(priv, 0x41, cdata, sizeof(cdata));987 988 dev_info(&priv->i2c->dev,989 "HELENE tuner x_pon done\n");990 991 return 0;992}993 994struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,995 const struct helene_config *config,996 struct i2c_adapter *i2c)997{998 struct helene_priv *priv = NULL;999 1000 priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL);1001 if (priv == NULL)1002 return NULL;1003 priv->i2c_address = (config->i2c_address >> 1);1004 priv->i2c = i2c;1005 priv->set_tuner_data = config->set_tuner_priv;1006 priv->set_tuner = config->set_tuner_callback;1007 priv->xtal = config->xtal;1008 1009 if (fe->ops.i2c_gate_ctrl)1010 fe->ops.i2c_gate_ctrl(fe, 1);1011 1012 if (helene_x_pon(priv) != 0) {1013 kfree(priv);1014 return NULL;1015 }1016 1017 if (fe->ops.i2c_gate_ctrl)1018 fe->ops.i2c_gate_ctrl(fe, 0);1019 1020 memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_s,1021 sizeof(struct dvb_tuner_ops));1022 fe->tuner_priv = priv;1023 dev_info(&priv->i2c->dev,1024 "Sony HELENE Sat attached on addr=%x at I2C adapter %p\n",1025 priv->i2c_address, priv->i2c);1026 return fe;1027}1028EXPORT_SYMBOL_GPL(helene_attach_s);1029 1030struct dvb_frontend *helene_attach(struct dvb_frontend *fe,1031 const struct helene_config *config,1032 struct i2c_adapter *i2c)1033{1034 struct helene_priv *priv = NULL;1035 1036 priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL);1037 if (priv == NULL)1038 return NULL;1039 priv->i2c_address = (config->i2c_address >> 1);1040 priv->i2c = i2c;1041 priv->set_tuner_data = config->set_tuner_priv;1042 priv->set_tuner = config->set_tuner_callback;1043 priv->xtal = config->xtal;1044 1045 if (fe->ops.i2c_gate_ctrl)1046 fe->ops.i2c_gate_ctrl(fe, 1);1047 1048 if (helene_x_pon(priv) != 0) {1049 kfree(priv);1050 return NULL;1051 }1052 1053 if (fe->ops.i2c_gate_ctrl)1054 fe->ops.i2c_gate_ctrl(fe, 0);1055 1056 memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_t,1057 sizeof(struct dvb_tuner_ops));1058 fe->tuner_priv = priv;1059 dev_info(&priv->i2c->dev,1060 "Sony HELENE Ter attached on addr=%x at I2C adapter %p\n",1061 priv->i2c_address, priv->i2c);1062 return fe;1063}1064EXPORT_SYMBOL_GPL(helene_attach);1065 1066static int helene_probe(struct i2c_client *client)1067{1068 struct helene_config *config = client->dev.platform_data;1069 struct dvb_frontend *fe = config->fe;1070 struct device *dev = &client->dev;1071 struct helene_priv *priv;1072 1073 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);1074 if (!priv)1075 return -ENOMEM;1076 1077 priv->i2c_address = client->addr;1078 priv->i2c = client->adapter;1079 priv->set_tuner_data = config->set_tuner_priv;1080 priv->set_tuner = config->set_tuner_callback;1081 priv->xtal = config->xtal;1082 1083 if (fe->ops.i2c_gate_ctrl)1084 fe->ops.i2c_gate_ctrl(fe, 1);1085 1086 if (helene_x_pon(priv) != 0)1087 return -EINVAL;1088 1089 if (fe->ops.i2c_gate_ctrl)1090 fe->ops.i2c_gate_ctrl(fe, 0);1091 1092 memcpy(&fe->ops.tuner_ops, &helene_tuner_ops,1093 sizeof(struct dvb_tuner_ops));1094 fe->tuner_priv = priv;1095 i2c_set_clientdata(client, priv);1096 1097 dev_info(dev, "Sony HELENE attached on addr=%x at I2C adapter %p\n",1098 priv->i2c_address, priv->i2c);1099 1100 return 0;1101}1102 1103static const struct i2c_device_id helene_id[] = {1104 { "helene", },1105 {}1106};1107MODULE_DEVICE_TABLE(i2c, helene_id);1108 1109static struct i2c_driver helene_driver = {1110 .driver = {1111 .name = "helene",1112 },1113 .probe = helene_probe,1114 .id_table = helene_id,1115};1116module_i2c_driver(helene_driver);1117 1118MODULE_DESCRIPTION("Sony HELENE Sat/Ter tuner driver");1119MODULE_AUTHOR("Abylay Ospan <aospan@netup.ru>");1120MODULE_LICENSE("GPL");1121