Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * helene.c
0004  *
0005  * Sony HELENE DVB-S/S2 DVB-T/T2 DVB-C/C2 ISDB-T/S tuner driver (CXD2858ER)
0006  *
0007  * Copyright 2012 Sony Corporation
0008  * Copyright (C) 2014 NetUP Inc.
0009  * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
0010   */
0011 
0012 #include <linux/slab.h>
0013 #include <linux/module.h>
0014 #include <linux/dvb/frontend.h>
0015 #include <linux/types.h>
0016 #include "helene.h"
0017 #include <media/dvb_frontend.h>
0018 
0019 #define MAX_WRITE_REGSIZE 20
0020 
0021 enum helene_state {
0022     STATE_UNKNOWN,
0023     STATE_SLEEP,
0024     STATE_ACTIVE
0025 };
0026 
0027 struct helene_priv {
0028     u32         frequency;
0029     u8          i2c_address;
0030     struct i2c_adapter  *i2c;
0031     enum helene_state   state;
0032     void            *set_tuner_data;
0033     int         (*set_tuner)(void *, int);
0034     enum helene_xtal xtal;
0035 };
0036 
0037 #define TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system) \
0038     (((tv_system) != SONY_HELENE_DTV_DVBC_6) && \
0039      ((tv_system) != SONY_HELENE_DTV_DVBC_8)\
0040      && ((tv_system) != SONY_HELENE_DTV_DVBC2_6) && \
0041      ((tv_system) != SONY_HELENE_DTV_DVBC2_8))
0042 
0043 #define HELENE_AUTO     0xff
0044 #define HELENE_OFFSET(ofs)  ((u8)(ofs) & 0x1F)
0045 #define HELENE_BW_6     0x00
0046 #define HELENE_BW_7     0x01
0047 #define HELENE_BW_8     0x02
0048 #define HELENE_BW_1_7       0x03
0049 
0050 enum helene_tv_system_t {
0051     SONY_HELENE_TV_SYSTEM_UNKNOWN,
0052     /* Terrestrial Analog */
0053     SONY_HELENE_ATV_MN_EIAJ,
0054     /**< System-M (Japan) (IF: Fp=5.75MHz in default) */
0055     SONY_HELENE_ATV_MN_SAP,
0056     /**< System-M (US)    (IF: Fp=5.75MHz in default) */
0057     SONY_HELENE_ATV_MN_A2,
0058     /**< System-M (Korea) (IF: Fp=5.9MHz in default) */
0059     SONY_HELENE_ATV_BG,
0060     /**< System-B/G       (IF: Fp=7.3MHz in default) */
0061     SONY_HELENE_ATV_I,
0062     /**< System-I         (IF: Fp=7.85MHz in default) */
0063     SONY_HELENE_ATV_DK,
0064     /**< System-D/K       (IF: Fp=7.85MHz in default) */
0065     SONY_HELENE_ATV_L,
0066     /**< System-L         (IF: Fp=7.85MHz in default) */
0067     SONY_HELENE_ATV_L_DASH,
0068     /**< System-L DASH    (IF: Fp=2.2MHz in default) */
0069     /* Terrestrial/Cable Digital */
0070     SONY_HELENE_DTV_8VSB,
0071     /**< ATSC 8VSB        (IF: Fc=3.7MHz in default) */
0072     SONY_HELENE_DTV_QAM,
0073     /**< US QAM           (IF: Fc=3.7MHz in default) */
0074     SONY_HELENE_DTV_ISDBT_6,
0075     /**< ISDB-T 6MHzBW    (IF: Fc=3.55MHz in default) */
0076     SONY_HELENE_DTV_ISDBT_7,
0077     /**< ISDB-T 7MHzBW    (IF: Fc=4.15MHz in default) */
0078     SONY_HELENE_DTV_ISDBT_8,
0079     /**< ISDB-T 8MHzBW    (IF: Fc=4.75MHz in default) */
0080     SONY_HELENE_DTV_DVBT_5,
0081     /**< DVB-T 5MHzBW     (IF: Fc=3.6MHz in default) */
0082     SONY_HELENE_DTV_DVBT_6,
0083     /**< DVB-T 6MHzBW     (IF: Fc=3.6MHz in default) */
0084     SONY_HELENE_DTV_DVBT_7,
0085     /**< DVB-T 7MHzBW     (IF: Fc=4.2MHz in default) */
0086     SONY_HELENE_DTV_DVBT_8,
0087     /**< DVB-T 8MHzBW     (IF: Fc=4.8MHz in default) */
0088     SONY_HELENE_DTV_DVBT2_1_7,
0089     /**< DVB-T2 1.7MHzBW  (IF: Fc=3.5MHz in default) */
0090     SONY_HELENE_DTV_DVBT2_5,
0091     /**< DVB-T2 5MHzBW    (IF: Fc=3.6MHz in default) */
0092     SONY_HELENE_DTV_DVBT2_6,
0093     /**< DVB-T2 6MHzBW    (IF: Fc=3.6MHz in default) */
0094     SONY_HELENE_DTV_DVBT2_7,
0095     /**< DVB-T2 7MHzBW    (IF: Fc=4.2MHz in default) */
0096     SONY_HELENE_DTV_DVBT2_8,
0097     /**< DVB-T2 8MHzBW    (IF: Fc=4.8MHz in default) */
0098     SONY_HELENE_DTV_DVBC_6,
0099     /**< DVB-C 6MHzBW     (IF: Fc=3.7MHz in default) */
0100     SONY_HELENE_DTV_DVBC_8,
0101     /**< DVB-C 8MHzBW     (IF: Fc=4.9MHz in default) */
0102     SONY_HELENE_DTV_DVBC2_6,
0103     /**< DVB-C2 6MHzBW    (IF: Fc=3.7MHz in default) */
0104     SONY_HELENE_DTV_DVBC2_8,
0105     /**< DVB-C2 8MHzBW    (IF: Fc=4.9MHz in default) */
0106     SONY_HELENE_DTV_DTMB,
0107     /**< DTMB             (IF: Fc=5.1MHz in default) */
0108     /* Satellite */
0109     SONY_HELENE_STV_ISDBS,
0110     /**< ISDB-S */
0111     SONY_HELENE_STV_DVBS,
0112     /**< DVB-S */
0113     SONY_HELENE_STV_DVBS2,
0114     /**< DVB-S2 */
0115 
0116     SONY_HELENE_ATV_MIN = SONY_HELENE_ATV_MN_EIAJ,
0117     /**< Minimum analog terrestrial system */
0118     SONY_HELENE_ATV_MAX = SONY_HELENE_ATV_L_DASH,
0119     /**< Maximum analog terrestrial system */
0120     SONY_HELENE_DTV_MIN = SONY_HELENE_DTV_8VSB,
0121     /**< Minimum digital terrestrial system */
0122     SONY_HELENE_DTV_MAX = SONY_HELENE_DTV_DTMB,
0123     /**< Maximum digital terrestrial system */
0124     SONY_HELENE_TERR_TV_SYSTEM_NUM,
0125     /**< Number of supported terrestrial broadcasting system */
0126     SONY_HELENE_STV_MIN = SONY_HELENE_STV_ISDBS,
0127     /**< Minimum satellite system */
0128     SONY_HELENE_STV_MAX = SONY_HELENE_STV_DVBS2
0129     /**< Maximum satellite system */
0130 };
0131 
0132 struct helene_terr_adjust_param_t {
0133     /* < Addr:0x69 Bit[6:4] : RFVGA gain.
0134      * 0xFF means Auto. (RF_GAIN_SEL = 1)
0135      */
0136     uint8_t RF_GAIN;
0137     /* < Addr:0x69 Bit[3:0] : IF_BPF gain.
0138     */
0139     uint8_t IF_BPF_GC;
0140     /* < Addr:0x6B Bit[3:0] : RF overload
0141      * RF input detect level. (FRF <= 172MHz)
0142     */
0143     uint8_t RFOVLD_DET_LV1_VL;
0144     /* < Addr:0x6B Bit[3:0] : RF overload
0145      * RF input detect level. (172MHz < FRF <= 464MHz)
0146     */
0147     uint8_t RFOVLD_DET_LV1_VH;
0148     /* < Addr:0x6B Bit[3:0] : RF overload
0149      * RF input detect level. (FRF > 464MHz)
0150     */
0151     uint8_t RFOVLD_DET_LV1_U;
0152     /* < Addr:0x6C Bit[2:0] :
0153      * Internal RFAGC detect level. (FRF <= 172MHz)
0154     */
0155     uint8_t IFOVLD_DET_LV_VL;
0156     /* < Addr:0x6C Bit[2:0] :
0157      * Internal RFAGC detect level. (172MHz < FRF <= 464MHz)
0158     */
0159     uint8_t IFOVLD_DET_LV_VH;
0160     /* < Addr:0x6C Bit[2:0] :
0161      * Internal RFAGC detect level. (FRF > 464MHz)
0162     */
0163     uint8_t IFOVLD_DET_LV_U;
0164     /* < Addr:0x6D Bit[5:4] :
0165      * IF filter center offset.
0166     */
0167     uint8_t IF_BPF_F0;
0168     /* < Addr:0x6D Bit[1:0] :
0169      * 6MHzBW(0x00) or 7MHzBW(0x01)
0170      * or 8MHzBW(0x02) or 1.7MHzBW(0x03)
0171     */
0172     uint8_t BW;
0173     /* < Addr:0x6E Bit[4:0] :
0174      * 5bit signed. IF offset (kHz) = FIF_OFFSET x 50
0175     */
0176     uint8_t FIF_OFFSET;
0177     /* < Addr:0x6F Bit[4:0] :
0178      * 5bit signed. BW offset (kHz) =
0179      * BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW)
0180     */
0181     uint8_t BW_OFFSET;
0182     /* < Addr:0x9C Bit[0]   :
0183      * Local polarity. (0: Upper Local, 1: Lower Local)
0184     */
0185     uint8_t IS_LOWERLOCAL;
0186 };
0187 
0188 static const struct helene_terr_adjust_param_t
0189 terr_params[SONY_HELENE_TERR_TV_SYSTEM_NUM] = {
0190     /*< SONY_HELENE_TV_SYSTEM_UNKNOWN */
0191     {HELENE_AUTO, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0192         HELENE_BW_6, HELENE_OFFSET(0),  HELENE_OFFSET(0),  0x00},
0193     /* Analog */
0194     /**< SONY_HELENE_ATV_MN_EIAJ   (System-M (Japan)) */
0195     {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
0196         HELENE_BW_6,  HELENE_OFFSET(0),  HELENE_OFFSET(1),  0x00},
0197     /**< SONY_HELENE_ATV_MN_SAP    (System-M (US)) */
0198     {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
0199         HELENE_BW_6,  HELENE_OFFSET(0),  HELENE_OFFSET(1),  0x00},
0200     {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
0201         HELENE_BW_6,  HELENE_OFFSET(3),  HELENE_OFFSET(1),  0x00},
0202     /**< SONY_HELENE_ATV_MN_A2     (System-M (Korea)) */
0203     {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
0204         HELENE_BW_7,  HELENE_OFFSET(11), HELENE_OFFSET(5),  0x00},
0205     /**< SONY_HELENE_ATV_BG        (System-B/G) */
0206     {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
0207         HELENE_BW_8,  HELENE_OFFSET(2),  HELENE_OFFSET(-3), 0x00},
0208     /**< SONY_HELENE_ATV_I         (System-I) */
0209     {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00,
0210         HELENE_BW_8,  HELENE_OFFSET(2),  HELENE_OFFSET(-3), 0x00},
0211     /**< SONY_HELENE_ATV_DK        (System-D/K) */
0212     {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00,
0213         HELENE_BW_8,  HELENE_OFFSET(2),  HELENE_OFFSET(-3), 0x00},
0214     /**< SONY_HELENE_ATV_L         (System-L) */
0215     {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00,
0216         HELENE_BW_8,  HELENE_OFFSET(-1), HELENE_OFFSET(4),  0x00},
0217     /**< SONY_HELENE_ATV_L_DASH    (System-L DASH) */
0218     /* Digital */
0219     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x03, 0x03, 0x03, 0x00,
0220         HELENE_BW_6,  HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00},
0221     /**< SONY_HELENE_DTV_8VSB      (ATSC 8VSB) */
0222     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0223         HELENE_BW_6,  HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00},
0224     /**< SONY_HELENE_DTV_QAM       (US QAM) */
0225     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0226         HELENE_BW_6,  HELENE_OFFSET(-9), HELENE_OFFSET(-5), 0x00},
0227     /**< SONY_HELENE_DTV_ISDBT_6   (ISDB-T 6MHzBW) */
0228     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0229         HELENE_BW_7,  HELENE_OFFSET(-7), HELENE_OFFSET(-6), 0x00},
0230     /**< SONY_HELENE_DTV_ISDBT_7   (ISDB-T 7MHzBW) */
0231     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0232         HELENE_BW_8,  HELENE_OFFSET(-5), HELENE_OFFSET(-7), 0x00},
0233     /**< SONY_HELENE_DTV_ISDBT_8   (ISDB-T 8MHzBW) */
0234     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0235         HELENE_BW_6,  HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
0236     /**< SONY_HELENE_DTV_DVBT_5    (DVB-T 5MHzBW) */
0237     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0238         HELENE_BW_6,  HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
0239     /**< SONY_HELENE_DTV_DVBT_6    (DVB-T 6MHzBW) */
0240     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0241         HELENE_BW_7,  HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00},
0242     /**< SONY_HELENE_DTV_DVBT_7    (DVB-T 7MHzBW) */
0243     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0244         HELENE_BW_8,  HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00},
0245     /**< SONY_HELENE_DTV_DVBT_8    (DVB-T 8MHzBW) */
0246     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0247         HELENE_BW_1_7, HELENE_OFFSET(-10), HELENE_OFFSET(-10), 0x00},
0248     /**< SONY_HELENE_DTV_DVBT2_1_7 (DVB-T2 1.7MHzBW) */
0249     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0250         HELENE_BW_6,  HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
0251     /**< SONY_HELENE_DTV_DVBT2_5   (DVB-T2 5MHzBW) */
0252     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0253         HELENE_BW_6,  HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00},
0254     /**< SONY_HELENE_DTV_DVBT2_6   (DVB-T2 6MHzBW) */
0255     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0256         HELENE_BW_7,  HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00},
0257     /**< SONY_HELENE_DTV_DVBT2_7   (DVB-T2 7MHzBW) */
0258     {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0259         HELENE_BW_8,  HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00},
0260     /**< SONY_HELENE_DTV_DVBT2_8   (DVB-T2 8MHzBW) */
0261     {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00,
0262         HELENE_BW_6,  HELENE_OFFSET(-6), HELENE_OFFSET(-4), 0x00},
0263     /**< SONY_HELENE_DTV_DVBC_6    (DVB-C 6MHzBW) */
0264     {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00,
0265         HELENE_BW_8,  HELENE_OFFSET(-2), HELENE_OFFSET(-3), 0x00},
0266     /**< SONY_HELENE_DTV_DVBC_8    (DVB-C 8MHzBW) */
0267     {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00,
0268         HELENE_BW_6,  HELENE_OFFSET(-6), HELENE_OFFSET(-2), 0x00},
0269     /**< SONY_HELENE_DTV_DVBC2_6   (DVB-C2 6MHzBW) */
0270     {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00,
0271         HELENE_BW_8,  HELENE_OFFSET(-2), HELENE_OFFSET(0),  0x00},
0272     /**< SONY_HELENE_DTV_DVBC2_8   (DVB-C2 8MHzBW) */
0273     {HELENE_AUTO, 0x04, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00,
0274         HELENE_BW_8,  HELENE_OFFSET(2),  HELENE_OFFSET(1),  0x00}
0275     /**< SONY_HELENE_DTV_DTMB      (DTMB) */
0276 };
0277 
0278 static void helene_i2c_debug(struct helene_priv *priv,
0279         u8 reg, u8 write, const u8 *data, u32 len)
0280 {
0281     dev_dbg(&priv->i2c->dev, "helene: I2C %s reg 0x%02x size %d\n",
0282             (write == 0 ? "read" : "write"), reg, len);
0283     print_hex_dump_bytes("helene: I2C data: ",
0284             DUMP_PREFIX_OFFSET, data, len);
0285 }
0286 
0287 static int helene_write_regs(struct helene_priv *priv,
0288         u8 reg, const u8 *data, u32 len)
0289 {
0290     int ret;
0291     u8 buf[MAX_WRITE_REGSIZE + 1];
0292     struct i2c_msg msg[1] = {
0293         {
0294             .addr = priv->i2c_address,
0295             .flags = 0,
0296             .len = len + 1,
0297             .buf = buf,
0298         }
0299     };
0300 
0301     if (len + 1 > sizeof(buf)) {
0302         dev_warn(&priv->i2c->dev,
0303                 "wr reg=%04x: len=%d vs %zu is too big!\n",
0304                 reg, len + 1, sizeof(buf));
0305         return -E2BIG;
0306     }
0307 
0308     helene_i2c_debug(priv, reg, 1, data, len);
0309     buf[0] = reg;
0310     memcpy(&buf[1], data, len);
0311     ret = i2c_transfer(priv->i2c, msg, 1);
0312     if (ret >= 0 && ret != 1)
0313         ret = -EREMOTEIO;
0314     if (ret < 0) {
0315         dev_warn(&priv->i2c->dev,
0316                 "%s: i2c wr failed=%d reg=%02x len=%d\n",
0317                 KBUILD_MODNAME, ret, reg, len);
0318         return ret;
0319     }
0320     return 0;
0321 }
0322 
0323 static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val)
0324 {
0325     u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
0326 
0327     return helene_write_regs(priv, reg, &tmp, 1);
0328 }
0329 
0330 static int helene_read_regs(struct helene_priv *priv,
0331         u8 reg, u8 *val, u32 len)
0332 {
0333     int ret;
0334     struct i2c_msg msg[2] = {
0335         {
0336             .addr = priv->i2c_address,
0337             .flags = 0,
0338             .len = 1,
0339             .buf = &reg,
0340         }, {
0341             .addr = priv->i2c_address,
0342             .flags = I2C_M_RD,
0343             .len = len,
0344             .buf = val,
0345         }
0346     };
0347 
0348     ret = i2c_transfer(priv->i2c, &msg[0], 1);
0349     if (ret >= 0 && ret != 1)
0350         ret = -EREMOTEIO;
0351     if (ret < 0) {
0352         dev_warn(&priv->i2c->dev,
0353                 "%s: I2C rw failed=%d addr=%02x reg=%02x\n",
0354                 KBUILD_MODNAME, ret, priv->i2c_address, reg);
0355         return ret;
0356     }
0357     ret = i2c_transfer(priv->i2c, &msg[1], 1);
0358     if (ret >= 0 && ret != 1)
0359         ret = -EREMOTEIO;
0360     if (ret < 0) {
0361         dev_warn(&priv->i2c->dev,
0362                 "%s: i2c rd failed=%d addr=%02x reg=%02x\n",
0363                 KBUILD_MODNAME, ret, priv->i2c_address, reg);
0364         return ret;
0365     }
0366     helene_i2c_debug(priv, reg, 0, val, len);
0367     return 0;
0368 }
0369 
0370 static int helene_read_reg(struct helene_priv *priv, u8 reg, u8 *val)
0371 {
0372     return helene_read_regs(priv, reg, val, 1);
0373 }
0374 
0375 static int helene_set_reg_bits(struct helene_priv *priv,
0376         u8 reg, u8 data, u8 mask)
0377 {
0378     int res;
0379     u8 rdata;
0380 
0381     if (mask != 0xff) {
0382         res = helene_read_reg(priv, reg, &rdata);
0383         if (res != 0)
0384             return res;
0385         data = ((data & mask) | (rdata & (mask ^ 0xFF)));
0386     }
0387     return helene_write_reg(priv, reg, data);
0388 }
0389 
0390 static int helene_enter_power_save(struct helene_priv *priv)
0391 {
0392     dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0393     if (priv->state == STATE_SLEEP)
0394         return 0;
0395 
0396     /* Standby setting for CPU */
0397     helene_write_reg(priv, 0x88, 0x0);
0398 
0399     /* Standby setting for internal logic block */
0400     helene_write_reg(priv, 0x87, 0xC0);
0401 
0402     priv->state = STATE_SLEEP;
0403     return 0;
0404 }
0405 
0406 static int helene_leave_power_save(struct helene_priv *priv)
0407 {
0408     dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0409     if (priv->state == STATE_ACTIVE)
0410         return 0;
0411 
0412     /* Standby setting for internal logic block */
0413     helene_write_reg(priv, 0x87, 0xC4);
0414 
0415     /* Standby setting for CPU */
0416     helene_write_reg(priv, 0x88, 0x40);
0417 
0418     priv->state = STATE_ACTIVE;
0419     return 0;
0420 }
0421 
0422 static int helene_init(struct dvb_frontend *fe)
0423 {
0424     struct helene_priv *priv = fe->tuner_priv;
0425 
0426     dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0427     return helene_leave_power_save(priv);
0428 }
0429 
0430 static void helene_release(struct dvb_frontend *fe)
0431 {
0432     struct helene_priv *priv = fe->tuner_priv;
0433 
0434     dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0435     kfree(fe->tuner_priv);
0436     fe->tuner_priv = NULL;
0437 }
0438 
0439 static int helene_sleep(struct dvb_frontend *fe)
0440 {
0441     struct helene_priv *priv = fe->tuner_priv;
0442 
0443     dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
0444     helene_enter_power_save(priv);
0445     return 0;
0446 }
0447 
0448 static enum helene_tv_system_t helene_get_tv_system(struct dvb_frontend *fe)
0449 {
0450     enum helene_tv_system_t system = SONY_HELENE_TV_SYSTEM_UNKNOWN;
0451     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0452     struct helene_priv *priv = fe->tuner_priv;
0453 
0454     if (p->delivery_system == SYS_DVBT) {
0455         if (p->bandwidth_hz <= 5000000)
0456             system = SONY_HELENE_DTV_DVBT_5;
0457         else if (p->bandwidth_hz <= 6000000)
0458             system = SONY_HELENE_DTV_DVBT_6;
0459         else if (p->bandwidth_hz <= 7000000)
0460             system = SONY_HELENE_DTV_DVBT_7;
0461         else if (p->bandwidth_hz <= 8000000)
0462             system = SONY_HELENE_DTV_DVBT_8;
0463         else {
0464             system = SONY_HELENE_DTV_DVBT_8;
0465             p->bandwidth_hz = 8000000;
0466         }
0467     } else if (p->delivery_system == SYS_DVBT2) {
0468         if (p->bandwidth_hz <= 5000000)
0469             system = SONY_HELENE_DTV_DVBT2_5;
0470         else if (p->bandwidth_hz <= 6000000)
0471             system = SONY_HELENE_DTV_DVBT2_6;
0472         else if (p->bandwidth_hz <= 7000000)
0473             system = SONY_HELENE_DTV_DVBT2_7;
0474         else if (p->bandwidth_hz <= 8000000)
0475             system = SONY_HELENE_DTV_DVBT2_8;
0476         else {
0477             system = SONY_HELENE_DTV_DVBT2_8;
0478             p->bandwidth_hz = 8000000;
0479         }
0480     } else if (p->delivery_system == SYS_DVBS) {
0481         system = SONY_HELENE_STV_DVBS;
0482     } else if (p->delivery_system == SYS_DVBS2) {
0483         system = SONY_HELENE_STV_DVBS2;
0484     } else if (p->delivery_system == SYS_ISDBS) {
0485         system = SONY_HELENE_STV_ISDBS;
0486     } else if (p->delivery_system == SYS_ISDBT) {
0487         if (p->bandwidth_hz <= 6000000)
0488             system = SONY_HELENE_DTV_ISDBT_6;
0489         else if (p->bandwidth_hz <= 7000000)
0490             system = SONY_HELENE_DTV_ISDBT_7;
0491         else if (p->bandwidth_hz <= 8000000)
0492             system = SONY_HELENE_DTV_ISDBT_8;
0493         else {
0494             system = SONY_HELENE_DTV_ISDBT_8;
0495             p->bandwidth_hz = 8000000;
0496         }
0497     } else if (p->delivery_system == SYS_DVBC_ANNEX_A) {
0498         if (p->bandwidth_hz <= 6000000)
0499             system = SONY_HELENE_DTV_DVBC_6;
0500         else if (p->bandwidth_hz <= 8000000)
0501             system = SONY_HELENE_DTV_DVBC_8;
0502     }
0503     dev_dbg(&priv->i2c->dev,
0504             "%s(): HELENE DTV system %d (delsys %d, bandwidth %d)\n",
0505             __func__, (int)system, p->delivery_system,
0506             p->bandwidth_hz);
0507     return system;
0508 }
0509 
0510 static int helene_set_params_s(struct dvb_frontend *fe)
0511 {
0512     u8 data[MAX_WRITE_REGSIZE];
0513     u32 frequency;
0514     enum helene_tv_system_t tv_system;
0515     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0516     struct helene_priv *priv = fe->tuner_priv;
0517     int frequencykHz = p->frequency;
0518     uint32_t frequency4kHz = 0;
0519     u32 symbol_rate = p->symbol_rate/1000;
0520 
0521     dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz sr=%uKsps\n",
0522             __func__, frequencykHz, symbol_rate);
0523     tv_system = helene_get_tv_system(fe);
0524 
0525     if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) {
0526         dev_err(&priv->i2c->dev, "%s(): unknown DTV system\n",
0527                 __func__);
0528         return -EINVAL;
0529     }
0530     /* RF switch turn to satellite */
0531     if (priv->set_tuner)
0532         priv->set_tuner(priv->set_tuner_data, 0);
0533     frequency = roundup(p->frequency / 1000, 1);
0534 
0535     /* Disable IF signal output */
0536     helene_write_reg(priv, 0x15, 0x02);
0537 
0538     /* RFIN matching in power save (Sat) reset */
0539     helene_write_reg(priv, 0x43, 0x06);
0540 
0541     /* Analog block setting (0x6A, 0x6B) */
0542     data[0] = 0x00;
0543     data[1] = 0x00;
0544     helene_write_regs(priv, 0x6A, data, 2);
0545     helene_write_reg(priv, 0x75, 0x99);
0546     helene_write_reg(priv, 0x9D, 0x00);
0547 
0548     /* Tuning setting for CPU (0x61) */
0549     helene_write_reg(priv, 0x61, 0x07);
0550 
0551     /* Satellite mode select (0x01) */
0552     helene_write_reg(priv, 0x01, 0x01);
0553 
0554     /* Clock enable for internal logic block, CPU wake-up (0x04, 0x05) */
0555     data[0] = 0xC4;
0556     data[1] = 0x40;
0557 
0558     switch (priv->xtal) {
0559     case SONY_HELENE_XTAL_16000:
0560         data[2] = 0x02;
0561         break;
0562     case SONY_HELENE_XTAL_20500:
0563         data[2] = 0x02;
0564         break;
0565     case SONY_HELENE_XTAL_24000:
0566         data[2] = 0x03;
0567         break;
0568     case SONY_HELENE_XTAL_41000:
0569         data[2] = 0x05;
0570         break;
0571     default:
0572         dev_err(&priv->i2c->dev, "%s(): unknown xtal %d\n",
0573                 __func__, priv->xtal);
0574         return -EINVAL;
0575     }
0576 
0577     /* Setting for analog block (0x07). LOOPFILTER INTERNAL */
0578     data[3] = 0x80;
0579 
0580     /* Tuning setting for analog block
0581      * (0x08, 0x09, 0x0A, 0x0B). LOOPFILTER INTERNAL
0582     */
0583     if (priv->xtal == SONY_HELENE_XTAL_20500)
0584         data[4] = 0x58;
0585     else
0586         data[4] = 0x70;
0587 
0588     data[5] = 0x1E;
0589     data[6] = 0x02;
0590     data[7] = 0x24;
0591 
0592     /* Enable for analog block (0x0C, 0x0D, 0x0E). SAT LNA ON */
0593     data[8] = 0x0F;
0594     data[8] |= 0xE0; /* POWERSAVE_TERR_RF_ACTIVE */
0595     data[9]  = 0x02;
0596     data[10] = 0x1E;
0597 
0598     /* Setting for LPF cutoff frequency (0x0F) */
0599     switch (tv_system) {
0600     case SONY_HELENE_STV_ISDBS:
0601         data[11] = 0x22; /* 22MHz */
0602         break;
0603     case SONY_HELENE_STV_DVBS:
0604         if (symbol_rate <= 4000)
0605             data[11] = 0x05;
0606         else if (symbol_rate <= 10000)
0607             data[11] = (uint8_t)((symbol_rate * 47
0608                         + (40000-1)) / 40000);
0609         else
0610             data[11] = (uint8_t)((symbol_rate * 27
0611                         + (40000-1)) / 40000 + 5);
0612 
0613         if (data[11] > 36)
0614             data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */
0615         break;
0616     case SONY_HELENE_STV_DVBS2:
0617         if (symbol_rate <= 4000)
0618             data[11] = 0x05;
0619         else if (symbol_rate <= 10000)
0620             data[11] = (uint8_t)((symbol_rate * 11
0621                         + (10000-1)) / 10000);
0622         else
0623             data[11] = (uint8_t)((symbol_rate * 3
0624                         + (5000-1)) / 5000 + 5);
0625 
0626         if (data[11] > 36)
0627             data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */
0628         break;
0629     default:
0630         dev_err(&priv->i2c->dev, "%s(): unknown standard %d\n",
0631                 __func__, tv_system);
0632         return -EINVAL;
0633     }
0634 
0635     /* RF tuning frequency setting (0x10, 0x11, 0x12) */
0636     frequency4kHz = (frequencykHz + 2) / 4;
0637     data[12] = (uint8_t)(frequency4kHz & 0xFF);         /* FRF_L */
0638     data[13] = (uint8_t)((frequency4kHz >> 8) & 0xFF);  /* FRF_M */
0639     /* FRF_H (bit[3:0]) */
0640     data[14] = (uint8_t)((frequency4kHz >> 16) & 0x0F);
0641 
0642     /* Tuning command (0x13) */
0643     data[15] = 0xFF;
0644 
0645     /* Setting for IQOUT_LIMIT (0x14) 0.75Vpp */
0646     data[16] = 0x00;
0647 
0648     /* Enable IQ output (0x15) */
0649     data[17] = 0x01;
0650 
0651     helene_write_regs(priv, 0x04, data, 18);
0652 
0653     dev_dbg(&priv->i2c->dev, "%s(): tune done\n",
0654             __func__);
0655 
0656     priv->frequency = frequency;
0657     return 0;
0658 }
0659 
0660 static int helene_set_params_t(struct dvb_frontend *fe)
0661 {
0662     u8 data[MAX_WRITE_REGSIZE];
0663     u32 frequency;
0664     enum helene_tv_system_t tv_system;
0665     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0666     struct helene_priv *priv = fe->tuner_priv;
0667     int frequencykHz = p->frequency / 1000;
0668 
0669     dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n",
0670             __func__, frequencykHz);
0671     tv_system = helene_get_tv_system(fe);
0672 
0673     if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) {
0674         dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n",
0675                 __func__);
0676         return -EINVAL;
0677     }
0678     if (priv->set_tuner)
0679         priv->set_tuner(priv->set_tuner_data, 1);
0680     frequency = roundup(p->frequency / 1000, 25);
0681 
0682     /* mode select */
0683     helene_write_reg(priv, 0x01, 0x00);
0684 
0685     /* Disable IF signal output */
0686     helene_write_reg(priv, 0x74, 0x02);
0687 
0688     if (priv->state == STATE_SLEEP)
0689         helene_leave_power_save(priv);
0690 
0691     /* Initial setting for internal analog block (0x91, 0x92) */
0692     if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
0693             (tv_system == SONY_HELENE_DTV_DVBC_8)) {
0694         data[0] = 0x16;
0695         data[1] = 0x26;
0696     } else {
0697         data[0] = 0x10;
0698         data[1] = 0x20;
0699     }
0700     helene_write_regs(priv, 0x91, data, 2);
0701 
0702     /* Setting for analog block */
0703     if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system))
0704         data[0] = 0x90;
0705     else
0706         data[0] = 0x00;
0707 
0708     /* Setting for local polarity (0x9D) */
0709     data[1] = (uint8_t)(terr_params[tv_system].IS_LOWERLOCAL & 0x01);
0710     helene_write_regs(priv, 0x9C, data, 2);
0711 
0712     /* Enable for analog block */
0713     data[0] = 0xEE;
0714     data[1] = 0x02;
0715     data[2] = 0x1E;
0716     data[3] = 0x67; /* Tuning setting for CPU */
0717 
0718     /* Setting for PLL reference divider for xtal=24MHz */
0719     if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
0720             (tv_system == SONY_HELENE_DTV_DVBC_8))
0721         data[4] = 0x18;
0722     else
0723         data[4] = 0x03;
0724 
0725     /* Tuning setting for analog block */
0726     if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system)) {
0727         data[5] = 0x38;
0728         data[6] = 0x1E;
0729         data[7] = 0x02;
0730         data[8] = 0x24;
0731     } else if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
0732             (tv_system == SONY_HELENE_DTV_DVBC_8)) {
0733         data[5] = 0x1C;
0734         data[6] = 0x78;
0735         data[7] = 0x08;
0736         data[8] = 0x1C;
0737     } else {
0738         data[5] = 0xB4;
0739         data[6] = 0x78;
0740         data[7] = 0x08;
0741         data[8] = 0x30;
0742     }
0743     helene_write_regs(priv, 0x5E, data, 9);
0744 
0745     /* LT_AMP_EN should be 0 */
0746     helene_set_reg_bits(priv, 0x67, 0x0, 0x02);
0747 
0748     /* Setting for IFOUT_LIMIT */
0749     data[0] = 0x00; /* 1.5Vpp */
0750 
0751     /* RF_GAIN setting */
0752     if (terr_params[tv_system].RF_GAIN == HELENE_AUTO)
0753         data[1] = 0x80; /* RF_GAIN_SEL = 1 */
0754     else
0755         data[1] = (uint8_t)((terr_params[tv_system].RF_GAIN
0756                     << 4) & 0x70);
0757 
0758     /* IF_BPF_GC setting */
0759     data[1] |= (uint8_t)(terr_params[tv_system].IF_BPF_GC & 0x0F);
0760 
0761     /* Setting for internal RFAGC (0x6A, 0x6B, 0x6C) */
0762     data[2] = 0x00;
0763     if (frequencykHz <= 172000) {
0764         data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VL
0765                 & 0x0F);
0766         data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VL
0767                 & 0x07);
0768     } else if (frequencykHz <= 464000) {
0769         data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VH
0770                 & 0x0F);
0771         data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VH
0772                 & 0x07);
0773     } else {
0774         data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_U
0775                 & 0x0F);
0776         data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_U
0777                 & 0x07);
0778     }
0779     data[4] |= 0x20;
0780 
0781     /* Setting for IF frequency and bandwidth */
0782 
0783     /* IF filter center frequency offset (IF_BPF_F0) (0x6D) */
0784     data[5] = (uint8_t)((terr_params[tv_system].IF_BPF_F0 << 4) & 0x30);
0785 
0786     /* IF filter band width (BW) (0x6D) */
0787     data[5] |= (uint8_t)(terr_params[tv_system].BW & 0x03);
0788 
0789     /* IF frequency offset value (FIF_OFFSET) (0x6E) */
0790     data[6] = (uint8_t)(terr_params[tv_system].FIF_OFFSET & 0x1F);
0791 
0792     /* IF band width offset value (BW_OFFSET) (0x6F) */
0793     data[7] = (uint8_t)(terr_params[tv_system].BW_OFFSET & 0x1F);
0794 
0795     /* RF tuning frequency setting (0x70, 0x71, 0x72) */
0796     data[8]  = (uint8_t)(frequencykHz & 0xFF);         /* FRF_L */
0797     data[9]  = (uint8_t)((frequencykHz >> 8) & 0xFF);  /* FRF_M */
0798     data[10] = (uint8_t)((frequencykHz >> 16)
0799             & 0x0F); /* FRF_H (bit[3:0]) */
0800 
0801     /* Tuning command */
0802     data[11] = 0xFF;
0803 
0804     /* Enable IF output, AGC and IFOUT pin selection (0x74) */
0805     data[12] = 0x01;
0806 
0807     if ((tv_system == SONY_HELENE_DTV_DVBC_6) ||
0808             (tv_system == SONY_HELENE_DTV_DVBC_8)) {
0809         data[13] = 0xD9;
0810         data[14] = 0x0F;
0811         data[15] = 0x24;
0812         data[16] = 0x87;
0813     } else {
0814         data[13] = 0x99;
0815         data[14] = 0x00;
0816         data[15] = 0x24;
0817         data[16] = 0x87;
0818     }
0819 
0820     helene_write_regs(priv, 0x68, data, 17);
0821 
0822     dev_dbg(&priv->i2c->dev, "%s(): tune done\n",
0823             __func__);
0824 
0825     priv->frequency = frequency;
0826     return 0;
0827 }
0828 
0829 static int helene_set_params(struct dvb_frontend *fe)
0830 {
0831     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0832 
0833     if (p->delivery_system == SYS_DVBT ||
0834         p->delivery_system == SYS_DVBT2 ||
0835         p->delivery_system == SYS_ISDBT ||
0836         p->delivery_system == SYS_DVBC_ANNEX_A)
0837         return helene_set_params_t(fe);
0838 
0839     return helene_set_params_s(fe);
0840 }
0841 
0842 static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0843 {
0844     struct helene_priv *priv = fe->tuner_priv;
0845 
0846     *frequency = priv->frequency * 1000;
0847     return 0;
0848 }
0849 
0850 static const struct dvb_tuner_ops helene_tuner_ops_t = {
0851     .info = {
0852         .name = "Sony HELENE Ter tuner",
0853         .frequency_min_hz  =    1 * MHz,
0854         .frequency_max_hz  = 1200 * MHz,
0855         .frequency_step_hz =   25 * kHz,
0856     },
0857     .init = helene_init,
0858     .release = helene_release,
0859     .sleep = helene_sleep,
0860     .set_params = helene_set_params_t,
0861     .get_frequency = helene_get_frequency,
0862 };
0863 
0864 static const struct dvb_tuner_ops helene_tuner_ops_s = {
0865     .info = {
0866         .name = "Sony HELENE Sat tuner",
0867         .frequency_min_hz  =  500 * MHz,
0868         .frequency_max_hz  = 2500 * MHz,
0869         .frequency_step_hz =    1 * MHz,
0870     },
0871     .init = helene_init,
0872     .release = helene_release,
0873     .sleep = helene_sleep,
0874     .set_params = helene_set_params_s,
0875     .get_frequency = helene_get_frequency,
0876 };
0877 
0878 static const struct dvb_tuner_ops helene_tuner_ops = {
0879     .info = {
0880         .name = "Sony HELENE Sat/Ter tuner",
0881         .frequency_min_hz  =    1 * MHz,
0882         .frequency_max_hz  = 2500 * MHz,
0883         .frequency_step_hz =   25 * kHz,
0884     },
0885     .init = helene_init,
0886     .release = helene_release,
0887     .sleep = helene_sleep,
0888     .set_params = helene_set_params,
0889     .get_frequency = helene_get_frequency,
0890 };
0891 
0892 /* power-on tuner
0893  * call once after reset
0894  */
0895 static int helene_x_pon(struct helene_priv *priv)
0896 {
0897     /* RFIN matching in power save (terrestrial) = ACTIVE */
0898     /* RFIN matching in power save (satellite) = ACTIVE */
0899     u8 dataT[] = { 0x06, 0x00, 0x02, 0x00 };
0900     /* SAT_RF_ACTIVE = true, lnaOff = false, terrRfActive = true */
0901     u8 dataS[] = { 0x05, 0x06 };
0902     u8 cdata[] = {0x7A, 0x01};
0903     u8 data[20];
0904     u8 rdata[2];
0905 
0906     /* mode select */
0907     helene_write_reg(priv, 0x01, 0x00);
0908 
0909     helene_write_reg(priv, 0x67, dataT[3]);
0910     helene_write_reg(priv, 0x43, dataS[1]);
0911     helene_write_regs(priv, 0x5E, dataT, 3);
0912     helene_write_reg(priv, 0x0C, dataS[0]);
0913 
0914     /* Initial setting for internal logic block */
0915     helene_write_regs(priv, 0x99, cdata, sizeof(cdata));
0916 
0917     /* 0x81 - 0x94 */
0918     if (priv->xtal == SONY_HELENE_XTAL_16000)
0919         data[0] = 0x10; /* xtal 16 MHz */
0920     else
0921         data[0] = 0x18; /* xtal 24 MHz */
0922     data[1] = (uint8_t)(0x80 | (0x04 & 0x1F)); /* 4 x 25 = 100uA */
0923     data[2] = (uint8_t)(0x80 | (0x26 & 0x7F)); /* 38 x 0.25 = 9.5pF */
0924     data[3] = 0x80; /* REFOUT signal output 500mVpp */
0925     data[4] = 0x00; /* GPIO settings */
0926     data[5] = 0x00; /* GPIO settings */
0927     data[6] = 0xC4; /* Clock enable for internal logic block */
0928     data[7] = 0x40; /* Start CPU boot-up */
0929     data[8] = 0x10; /* For burst-write */
0930 
0931     /* Setting for internal RFAGC */
0932     data[9] = 0x00;
0933     data[10] = 0x45;
0934     data[11] = 0x75;
0935 
0936     data[12] = 0x07; /* Setting for analog block */
0937 
0938     /* Initial setting for internal analog block */
0939     data[13] = 0x1C;
0940     data[14] = 0x3F;
0941     data[15] = 0x02;
0942     data[16] = 0x10;
0943     data[17] = 0x20;
0944     data[18] = 0x0A;
0945     data[19] = 0x00;
0946 
0947     helene_write_regs(priv, 0x81, data, sizeof(data));
0948 
0949     /* Setting for internal RFAGC */
0950     helene_write_reg(priv, 0x9B, 0x00);
0951 
0952     msleep(20);
0953 
0954     /* Check CPU_STT/CPU_ERR */
0955     helene_read_regs(priv, 0x1A, rdata, sizeof(rdata));
0956 
0957     if (rdata[0] != 0x00) {
0958         dev_err(&priv->i2c->dev,
0959                 "HELENE tuner CPU error 0x%x\n", rdata[0]);
0960         return -EIO;
0961     }
0962 
0963     /* VCO current setting */
0964     cdata[0] = 0x90;
0965     cdata[1] = 0x06;
0966     helene_write_regs(priv, 0x17, cdata, sizeof(cdata));
0967     msleep(20);
0968     helene_read_reg(priv, 0x19, data);
0969     helene_write_reg(priv, 0x95, (uint8_t)((data[0] >> 4) & 0x0F));
0970 
0971     /* Disable IF signal output */
0972     helene_write_reg(priv, 0x74, 0x02);
0973 
0974     /* Standby setting for CPU */
0975     helene_write_reg(priv, 0x88, 0x00);
0976 
0977     /* Standby setting for internal logic block */
0978     helene_write_reg(priv, 0x87, 0xC0);
0979 
0980     /* Load capacitance control setting for crystal oscillator */
0981     helene_write_reg(priv, 0x80, 0x01);
0982 
0983     /* Satellite initial setting */
0984     cdata[0] = 0x07;
0985     cdata[1] = 0x00;
0986     helene_write_regs(priv, 0x41, cdata, sizeof(cdata));
0987 
0988     dev_info(&priv->i2c->dev,
0989             "HELENE tuner x_pon done\n");
0990 
0991     return 0;
0992 }
0993 
0994 struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe,
0995         const struct helene_config *config,
0996         struct i2c_adapter *i2c)
0997 {
0998     struct helene_priv *priv = NULL;
0999 
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 }
1028 EXPORT_SYMBOL(helene_attach_s);
1029 
1030 struct 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 }
1064 EXPORT_SYMBOL(helene_attach);
1065 
1066 static int helene_probe(struct i2c_client *client,
1067             const struct i2c_device_id *id)
1068 {
1069     struct helene_config *config = client->dev.platform_data;
1070     struct dvb_frontend *fe = config->fe;
1071     struct device *dev = &client->dev;
1072     struct helene_priv *priv;
1073 
1074     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1075     if (!priv)
1076         return -ENOMEM;
1077 
1078     priv->i2c_address = client->addr;
1079     priv->i2c = client->adapter;
1080     priv->set_tuner_data = config->set_tuner_priv;
1081     priv->set_tuner = config->set_tuner_callback;
1082     priv->xtal = config->xtal;
1083 
1084     if (fe->ops.i2c_gate_ctrl)
1085         fe->ops.i2c_gate_ctrl(fe, 1);
1086 
1087     if (helene_x_pon(priv) != 0)
1088         return -EINVAL;
1089 
1090     if (fe->ops.i2c_gate_ctrl)
1091         fe->ops.i2c_gate_ctrl(fe, 0);
1092 
1093     memcpy(&fe->ops.tuner_ops, &helene_tuner_ops,
1094            sizeof(struct dvb_tuner_ops));
1095     fe->tuner_priv = priv;
1096     i2c_set_clientdata(client, priv);
1097 
1098     dev_info(dev, "Sony HELENE attached on addr=%x at I2C adapter %p\n",
1099          priv->i2c_address, priv->i2c);
1100 
1101     return 0;
1102 }
1103 
1104 static const struct i2c_device_id helene_id[] = {
1105     { "helene", },
1106     {}
1107 };
1108 MODULE_DEVICE_TABLE(i2c, helene_id);
1109 
1110 static struct i2c_driver helene_driver = {
1111     .driver = {
1112         .name = "helene",
1113     },
1114     .probe    = helene_probe,
1115     .id_table = helene_id,
1116 };
1117 module_i2c_driver(helene_driver);
1118 
1119 MODULE_DESCRIPTION("Sony HELENE Sat/Ter tuner driver");
1120 MODULE_AUTHOR("Abylay Ospan <aospan@netup.ru>");
1121 MODULE_LICENSE("GPL");