11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 3de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann i2c tv tuner chip device driver 4de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann controls the philips tda8290+75 tuner chip combo. 5de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 6de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann This program is free software; you can redistribute it and/or modify 7de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann it under the terms of the GNU General Public License as published by 8de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann the Free Software Foundation; either version 2 of the License, or 9de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann (at your option) any later version. 10de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 11de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann This program is distributed in the hope that it will be useful, 12de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann but WITHOUT ANY WARRANTY; without even the implied warranty of 13de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann GNU General Public License for more details. 15de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 16de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann You should have received a copy of the GNU General Public License 17de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann along with this program; if not, write to the Free Software 18de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 20910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky This "tda8290" module was split apart from the original "tuner" module. 21de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann*/ 22de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h> 245a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 267f6adeaf2d8800b66c5dd6c2cf2622dfdd68bd31Hans Verkuil#include <linux/videodev2.h> 27ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky#include "tuner-i2c.h" 28910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky#include "tda8290.h" 29746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky#include "tda827x.h" 305bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky#include "tda18271.h" 31910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 32ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufkystatic int debug; 33ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufkymodule_param(debug, int, 0644); 34910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael KrufkyMODULE_PARM_DESC(debug, "enable verbose debug messages"); 35910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 369af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehabstatic int deemphasis_50; 37b450b92e162a454b82fea6373c83e447e28ce4d6Henk Vergonetmodule_param(deemphasis_50, int, 0644); 389af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho ChehabMODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis"); 399af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ---------------------------------------------------------------------- */ 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufkystruct tda8290_priv { 43db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky struct tuner_i2c_props i2c_props; 44db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 45b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky unsigned char tda8290_easy_mode; 46746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 47b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky unsigned char tda827x_addr; 488c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 498c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky unsigned char ver; 508c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8290 1 518c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8295 2 528c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8275 4 538c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8275A 8 548c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA18271 16 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 56746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky struct tda827x_config cfg; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufkystatic int tda8290_i2c_bridge(struct dvb_frontend *fe, int close) 62de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann{ 634e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 64db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 65de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char enable[2] = { 0x21, 0xC0 }; 660157a9cc727dec90a7d60ad254eb899a775685a9Hartmut Hackmann unsigned char disable[2] = { 0x21, 0x00 }; 67de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char *msg; 68a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 69a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky if (close) { 70de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg = enable; 71db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 72de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* let the bridge stabilize */ 73de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(20); 74de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } else { 75de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg = disable; 76db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 77de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 78a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 79a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky return 0; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 82a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufkystatic int tda8295_i2c_bridge(struct dvb_frontend *fe, int close) 835bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 844e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 855bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 865bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char enable[2] = { 0x45, 0xc1 }; 875bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char disable[2] = { 0x46, 0x00 }; 885bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[3] = { 0x45, 0x01, 0x00 }; 895bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char *msg; 90a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 915bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (close) { 925bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msg = enable; 935bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 945bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky /* let the bridge stabilize */ 955bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(20); 965bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } else { 975bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msg = disable; 98567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1); 995bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 1005bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[2] = msg[1]; 1015bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[2] &= ~0x04; 1025bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 3); 1035bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(5); 1045bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 1055bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msg[1] |= 0x04; 1065bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 1075bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 108a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 109a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky return 0; 1105bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 1115bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 112de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 113de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 114c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufkystatic void set_audio(struct dvb_frontend *fe, 115c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky struct analog_parameters *params) 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1174e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 118910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky char* mode; 119910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 120c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky if (params->std & V4L2_STD_MN) { 121910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x01; 122910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "MN"; 123c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_B) { 124910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x02; 125910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "B"; 126c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_GH) { 127910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x04; 128910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "GH"; 129c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_PAL_I) { 130910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x08; 131910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "I"; 132c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_DK) { 133910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x10; 134910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "DK"; 135c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_SECAM_L) { 136910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x20; 137910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "L"; 138c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_SECAM_LC) { 139910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x40; 140910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "LC"; 141910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky } else { 142910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x10; 143910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "xx"; 144910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky } 145910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 1469af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab if (params->mode == V4L2_TUNER_RADIO) { 1473f76cf8c8ed10da1ce50f821366d0dc590397069Michael Krufky /* Set TDA8295 to FM radio; Start TDA8290 with MN values */ 1483f76cf8c8ed10da1ce50f821366d0dc590397069Michael Krufky priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01; 1499af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_dbg("setting to radio FM\n"); 1509af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab } else { 1519af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_dbg("setting tda829x to system %s\n", mode); 1529af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab } 153910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky} 154910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 1554c27f1a4da4902c70b84a8bce66f8fe909fb829bMauro Carvalho Chehabstatic struct { 1569af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab unsigned char seq[2]; 1579af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab} fm_mode[] = { 1589af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x01, 0x81} }, /* Put device into expert mode */ 1599af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x03, 0x48} }, /* Disable NOTCH and VIDEO filters */ 1609af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x04, 0x04} }, /* Disable color carrier filter (SSIF) */ 1619af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x05, 0x04} }, /* ADC headroom */ 1629af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x06, 0x10} }, /* group delay flat */ 1639af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 1649af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x07, 0x00} }, /* use the same radio DTO values as a tda8295 */ 1659af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x08, 0x00} }, 1669af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x09, 0x80} }, 1679af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x0a, 0xda} }, 1689af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x0b, 0x4b} }, 1699af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x0c, 0x68} }, 1709af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 1719af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x0d, 0x00} }, /* PLL off, no video carrier detect */ 1729af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab { { 0x14, 0x00} }, /* disable auto mute if no video */ 1739af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab}; 1749af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 175c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufkystatic void tda8290_set_params(struct dvb_frontend *fe, 176c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky struct analog_parameters *params) 177910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky{ 1784e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 1794e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky 180de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char soft_reset[] = { 0x00, 0x00 }; 181b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; 182de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char expert_mode[] = { 0x01, 0x80 }; 1830157a9cc727dec90a7d60ad254eb899a775685a9Hartmut Hackmann unsigned char agc_out_on[] = { 0x02, 0x00 }; 184de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char gainset_off[] = { 0x28, 0x14 }; 185de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char if_agc_spd[] = { 0x0f, 0x88 }; 186de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_head_6[] = { 0x05, 0x04 }; 187de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_head_9[] = { 0x05, 0x02 }; 188de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_head_12[] = { 0x05, 0x01 }; 189de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char pll_bw_nom[] = { 0x0d, 0x47 }; 190de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char pll_bw_low[] = { 0x0d, 0x27 }; 191de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char gainset_2[] = { 0x28, 0x64 }; 192de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char agc_rst_on[] = { 0x0e, 0x0b }; 193de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char agc_rst_off[] = { 0x0e, 0x09 }; 194de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char if_agc_set[] = { 0x0f, 0x81 }; 195de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char addr_adc_sat = 0x1a; 196de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char addr_agc_stat = 0x1d; 197de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char addr_pll_stat = 0x1b; 198de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_sat, agc_stat, 1999a741ec9b87ac13f13a1dfcb05979d7c785d0755Nickolay V. Shmyrev pll_stat; 20058ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann int i; 201de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 202c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky set_audio(fe, params); 203910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 204ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (priv->cfg.config) 2057bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config); 206db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); 207db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); 208db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); 209de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(1); 210de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 2119af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab if (params->mode == V4L2_TUNER_RADIO) { 2129af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab unsigned char deemphasis[] = { 0x13, 1 }; 2139af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 2149af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab /* FIXME: allow using a different deemphasis */ 2159af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 2169af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab if (deemphasis_50) 2179af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab deemphasis[1] = 2; 2189af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 2199af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab for (i = 0; i < ARRAY_SIZE(fm_mode); i++) 2209af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2); 2219af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab 2229af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2); 2239af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab } else { 2249af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab expert_mode[1] = priv->tda8290_easy_mode + 0x80; 2259af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2); 2269af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2); 2279af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2); 2289af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab if (priv->tda8290_easy_mode & 0x60) 2299af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2); 2309af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab else 2319af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); 2329af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); 2339af0ef27a06f3e8976b90a4ed4758e25ea0f2df5Mauro Carvalho Chehab } 234de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 235ecb71d262b0323981e07ce415da9b7adc917990aMauro Carvalho Chehab 2364e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 1); 237746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 2384e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (fe->ops.tuner_ops.set_analog_params) 239c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky fe->ops.tuner_ops.set_analog_params(fe, params); 240746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 24158ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann for (i = 0; i < 3; i++) { 242567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 243567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_pll_stat, 1, &pll_stat, 1); 24458ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann if (pll_stat & 0x80) { 245567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 246567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_adc_sat, 1, 247567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &adc_sat, 1); 248567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 249567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_agc_stat, 1, 250567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &agc_stat, 1); 25158ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); 25258ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann break; 25358ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann } else { 25458ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann tuner_dbg("tda8290 not locked, no signal?\n"); 25558ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann msleep(100); 25658ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann } 25758ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann } 258de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* adjust headroom resp. gain */ 2594ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { 2604ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", 2614ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann agc_stat, adc_sat, pll_stat & 0x80); 262db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); 263de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(100); 264567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 265567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_agc_stat, 1, &agc_stat, 1); 266567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 267567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_pll_stat, 1, &pll_stat, 1); 268de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if ((agc_stat > 115) || !(pll_stat & 0x80)) { 2694ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", 2704ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann agc_stat, pll_stat & 0x80); 271746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky if (priv->cfg.agcf) 2724e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky priv->cfg.agcf(fe); 273de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(100); 274567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 275567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_agc_stat, 1, 276567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &agc_stat, 1); 277567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 278567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_pll_stat, 1, 279567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &pll_stat, 1); 280de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if((agc_stat > 115) || !(pll_stat & 0x80)) { 281de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); 282db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); 283db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2); 284de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(100); 285de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 286de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 287de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 289de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* l/ l' deadlock? */ 290b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky if(priv->tda8290_easy_mode & 0x60) { 291567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 292567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_adc_sat, 1, 293567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &adc_sat, 1); 294567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 295567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_pll_stat, 1, 296567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &pll_stat, 1); 297de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if ((adc_sat > 20) || !(pll_stat & 0x80)) { 2984ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann tuner_dbg("trying to resolve SECAM L deadlock\n"); 299db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2); 300de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(40); 301db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2); 302de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 303de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 304586b0cab2516640fec4dffc3049c4d8bca188f89Mauro Carvalho Chehab 3054e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 0); 306db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 309de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 310de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 3114e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_power(struct dvb_frontend *fe, int enable) 3125bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3134e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3145bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ 3155bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 316567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); 3175bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3185bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) 3195bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x01; 3205bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 3215bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x03; 3225bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3235bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 3245bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3255bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3264e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable) 3275bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3284e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3295bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x01, 0x00 }; 3305bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 331567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); 3325bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3335bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) 3345bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ 3355bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 3365bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x00; /* reset active bit */ 3375bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3385bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 3395bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3405bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3414e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_set_video_std(struct dvb_frontend *fe) 3425bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3434e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3445bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x00, priv->tda8290_easy_mode }; 3455bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3465bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 3475bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3484e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_easy_mode(fe, 1); 3495bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(20); 3504e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_easy_mode(fe, 0); 3515bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3525bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3535bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky/*---------------------------------------------------------------------*/ 3545bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3554e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_agc1_out(struct dvb_frontend *fe, int enable) 3565bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3574e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3585bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ 3595bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 360567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1); 3615bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3625bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) 3635bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] &= ~0x40; 3645bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 3655bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] |= 0x40; 3665bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3675bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 3685bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3695bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3704e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_agc2_out(struct dvb_frontend *fe, int enable) 3715bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3724e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3735bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char set_gpio_cf[] = { 0x44, 0x00 }; 3745bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char set_gpio_val[] = { 0x46, 0x00 }; 3755bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 376567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 377567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &set_gpio_cf[0], 1, &set_gpio_cf[1], 1); 378567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 379567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &set_gpio_val[0], 1, &set_gpio_val[1], 1); 3805bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3815bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ 3825bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3835bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) { 3845bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */ 3855bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */ 3865bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 3875bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2); 3885bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2); 3895bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3905bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3914e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic int tda8295_has_signal(struct dvb_frontend *fe) 3925bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3934e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3945bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3955bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char hvpll_stat = 0x26; 3965bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char ret; 3975bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 398567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1); 3995bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky return (ret & 0x01) ? 65535 : 0; 4005bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 4015bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4025bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky/*---------------------------------------------------------------------*/ 4035bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 404c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufkystatic void tda8295_set_params(struct dvb_frontend *fe, 405c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky struct analog_parameters *params) 4065bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 4074e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 4085bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4095bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char blanking_mode[] = { 0x1d, 0x00 }; 4105bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 411c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky set_audio(fe, params); 4125bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4137e28adb2497f6b873516163e2d29210c11777613Harvey Harrison tuner_dbg("%s: freq = %d\n", __func__, params->frequency); 4145bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4154e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_power(fe, 1); 4164e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc1_out(fe, 1); 4175bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 418567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 419567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &blanking_mode[0], 1, &blanking_mode[1], 1); 4205bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4214e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_video_std(fe); 4225bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4235bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky blanking_mode[1] = 0x03; 4245bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); 4255bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(20); 4265bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4274e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_i2c_bridge(fe, 1); 4285bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4294e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (fe->ops.tuner_ops.set_analog_params) 430c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky fe->ops.tuner_ops.set_analog_params(fe, params); 4315bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4325bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (priv->cfg.agcf) 4334e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky priv->cfg.agcf(fe); 4345bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4354e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (tda8295_has_signal(fe)) 4365bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_dbg("tda8295 is locked\n"); 4375bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 4385bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_dbg("tda8295 not locked, no signal?\n"); 4395bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4404e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_i2c_bridge(fe, 0); 4415bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 4425bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4435bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky/*---------------------------------------------------------------------*/ 4445bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4454e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic int tda8290_has_signal(struct dvb_frontend *fe) 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4474e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 449910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky unsigned char i2c_get_afc[1] = { 0x1B }; 450910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky unsigned char afc = 0; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 452567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&priv->i2c_props, 453567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1); 454746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky return (afc & 0x80)? 65535:0; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 457de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 458de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4594e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8290_standby(struct dvb_frontend *fe) 460793cf9e6a54c698e109a599c8b8e303658fcaae6Mauro Carvalho Chehab{ 4614e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 4624e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky 463de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char cb1[] = { 0x30, 0xD0 }; 464de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char tda8290_standby[] = { 0x00, 0x02 }; 4650157a9cc727dec90a7d60ad254eb899a775685a9Hartmut Hackmann unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; 466b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; 467de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4684e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 1); 4698c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (priv->ver & TDA8275A) 470de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann cb1[1] = 0x90; 471db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky i2c_transfer(priv->i2c_props.adap, &msg, 1); 4724e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 0); 473db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); 474db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); 475793cf9e6a54c698e109a599c8b8e303658fcaae6Mauro Carvalho Chehab} 476793cf9e6a54c698e109a599c8b8e303658fcaae6Mauro Carvalho Chehab 4774e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_standby(struct dvb_frontend *fe) 4785bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 4794e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */ 4805bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4814e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_power(fe, 0); 4825bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 4835bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4844e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8290_init_if(struct dvb_frontend *fe) 485de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann{ 4864e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 487db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 488de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char set_VS[] = { 0x30, 0x6F }; 48958ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann unsigned char set_GP00_CF[] = { 0x20, 0x01 }; 490de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char set_GP01_CF[] = { 0x20, 0x0B }; 491de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4927bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann if ((priv->cfg.config == 1) || (priv->cfg.config == 2)) 493db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); 49458ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann else 495db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); 496db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2); 497de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann} 498de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4994e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_init_if(struct dvb_frontend *fe) 5005bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 5014e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 5025bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 5035bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_adc_ctl[] = { 0x33, 0x14 }; 5045bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_adc_ctl2[] = { 0x34, 0x00 }; 5055bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg6[] = { 0x3e, 0x63 }; 5065bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg0[] = { 0x38, 0x23 }; 5075bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg7[] = { 0x3f, 0x01 }; 5085bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg10[] = { 0x42, 0x61 }; 5095bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_gpio_reg0[] = { 0x44, 0x0b }; 5105bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 5114e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_power(fe, 1); 5125bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 5134e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_easy_mode(fe, 0); 5144e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_video_std(fe); 5155bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 5165bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2); 5175bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2); 5185bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2); 5195bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2); 5205bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2); 5215bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2); 5225bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2); 5235bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 5244e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc1_out(fe, 0); 5254e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc2_out(fe, 0); 5265bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 5275bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 5284e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8290_init_tuner(struct dvb_frontend *fe) 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5304e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 531de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, 5329a741ec9b87ac13f13a1dfcb05979d7c785d0755Nickolay V. Shmyrev 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; 533de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, 5349a741ec9b87ac13f13a1dfcb05979d7c785d0755Nickolay V. Shmyrev 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; 535b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, 536c2f6f9d866d3ea25eebe32c6c51e47e5141669cfRicardo Cerqueira .buf=tda8275_init, .len = 14}; 5378c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (priv->ver & TDA8275A) 538de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.buf = tda8275a_init; 539de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 5404e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 1); 541db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky i2c_transfer(priv->i2c_props.adap, &msg, 1); 5424e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 0); 543de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann} 544de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 545de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5474e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda829x_release(struct dvb_frontend *fe) 548024cf53089f7c8e58934407f07ca2a7b5bed3b06Michael Krufky{ 549a4f263b587573f47cc6bc7ad85e5f650169d48f6Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 550a4f263b587573f47cc6bc7ad85e5f650169d48f6Michael Krufky 551006ed1ecf2c62659e5dd902350a7eb209b8a5257Michael Krufky /* only try to release the tuner if we've 552006ed1ecf2c62659e5dd902350a7eb209b8a5257Michael Krufky * attached it from within this module */ 553006ed1ecf2c62659e5dd902350a7eb209b8a5257Michael Krufky if (priv->ver & (TDA18271 | TDA8275 | TDA8275A)) 554a4f263b587573f47cc6bc7ad85e5f650169d48f6Michael Krufky if (fe->ops.tuner_ops.release) 555a4f263b587573f47cc6bc7ad85e5f650169d48f6Michael Krufky fe->ops.tuner_ops.release(fe); 556024cf53089f7c8e58934407f07ca2a7b5bed3b06Michael Krufky 5574e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky kfree(fe->analog_demod_priv); 5584e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky fe->analog_demod_priv = NULL; 559910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky} 560910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 561f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufkystatic struct tda18271_config tda829x_tda18271_config = { 562f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky .gate = TDA18271_GATE_ANALOG, 563f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky}; 564f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky 5658c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufkystatic int tda829x_find_tuner(struct dvb_frontend *fe) 566de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann{ 5678c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 568bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky struct analog_demod_ops *analog_ops = &fe->ops.analog_ops; 569de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann int i, ret, tuners_found; 570de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann u32 tuner_addrs; 5718c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky u8 data; 5728c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; 573de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 57431063814400cd37d47f5f58a96e58596196f04b0Mauro Carvalho Chehab if (!analog_ops->i2c_gate_ctrl) { 57531063814400cd37d47f5f58a96e58596196f04b0Mauro Carvalho Chehab printk(KERN_ERR "tda8290: no gate control were provided!\n"); 57631063814400cd37d47f5f58a96e58596196f04b0Mauro Carvalho Chehab 5778c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky return -EINVAL; 57831063814400cd37d47f5f58a96e58596196f04b0Mauro Carvalho Chehab } 579746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 580bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky analog_ops->i2c_gate_ctrl(fe, 1); 581db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 582de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* probe for tuner chip */ 583de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuners_found = 0; 584de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = 0; 5858c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky for (i = 0x60; i <= 0x63; i++) { 586de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.addr = i; 587db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 588de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if (ret == 1) { 589de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuners_found++; 590de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = (tuner_addrs << 8) + i; 591de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 592de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 593de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* if there is more than one tuner, we expect the right one is 594de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann behind the bridge and we choose the highest address that doesn't 595de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann give a response now 596de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann */ 5978c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 598bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky analog_ops->i2c_gate_ctrl(fe, 0); 5998c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 6008c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (tuners_found > 1) 601de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann for (i = 0; i < tuners_found; i++) { 602de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.addr = tuner_addrs & 0xff; 603db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 6048c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (ret == 1) 605de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = tuner_addrs >> 8; 606de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann else 607de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann break; 608de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 6098c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 610de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if (tuner_addrs == 0) { 6118c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_addrs = 0x60; 6128c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_info("could not clearly identify tuner address, " 6138c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky "defaulting to %x\n", tuner_addrs); 614de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } else { 615de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = tuner_addrs & 0xff; 616910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_info("setting tuner address to %x\n", tuner_addrs); 617de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 618b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky priv->tda827x_addr = tuner_addrs; 619de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.addr = tuner_addrs; 620de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 621bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky analog_ops->i2c_gate_ctrl(fe, 1); 622db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 623910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 6248c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (ret != 1) { 6258c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_warn("tuner access failed!\n"); 62631063814400cd37d47f5f58a96e58596196f04b0Mauro Carvalho Chehab analog_ops->i2c_gate_ctrl(fe, 0); 6278c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky return -EREMOTEIO; 628de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 629746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 630255b5113b4ed683898a24e381155c081f03411f7Michael Krufky if ((data == 0x83) || (data == 0x84)) { 6318c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver |= TDA18271; 632adcc4b3e75c5f0293806766bcc5ed0bb62d5cda0Michael Krufky tda829x_tda18271_config.config = priv->cfg.config; 633a07c8779fd212dcbad886a2824ef5f8b42cd5a06Michael Krufky dvb_attach(tda18271_attach, fe, priv->tda827x_addr, 634a07c8779fd212dcbad886a2824ef5f8b42cd5a06Michael Krufky priv->i2c_props.adap, &tda829x_tda18271_config); 6358c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky } else { 6368c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if ((data & 0x3c) == 0) 6378c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver |= TDA8275; 6388c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky else 6398c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver |= TDA8275A; 6407fd8b263678ab8430b49c99976ade681f8a78439Michael Krufky 641a07c8779fd212dcbad886a2824ef5f8b42cd5a06Michael Krufky dvb_attach(tda827x_attach, fe, priv->tda827x_addr, 642a07c8779fd212dcbad886a2824ef5f8b42cd5a06Michael Krufky priv->i2c_props.adap, &priv->cfg); 6437bff4b4d3ad2b9ff42b4087f409076035af1d165Hartmut Hackmann priv->cfg.switch_addr = priv->i2c_props.addr; 6448c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky } 6456881647cce09931f3d787ab83b5250436427ceb9Michael Krufky if (fe->ops.tuner_ops.init) 6466881647cce09931f3d787ab83b5250436427ceb9Michael Krufky fe->ops.tuner_ops.init(fe); 64763c254805e38bad4c64b5f5b0e135a2a357fa0bfMichael Krufky 6486881647cce09931f3d787ab83b5250436427ceb9Michael Krufky if (fe->ops.tuner_ops.sleep) 6496881647cce09931f3d787ab83b5250436427ceb9Michael Krufky fe->ops.tuner_ops.sleep(fe); 65063c254805e38bad4c64b5f5b0e135a2a357fa0bfMichael Krufky 651bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky analog_ops->i2c_gate_ctrl(fe, 0); 652746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 653746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky return 0; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6555bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 656f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufkystatic int tda8290_probe(struct tuner_i2c_props *i2c_props) 657f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky{ 658f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky#define TDA8290_ID 0x89 659567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab u8 reg = 0x1f, id; 660567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab struct i2c_msg msg_read[] = { 66189a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = ® }, 66289a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id }, 663567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab }; 664f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 665f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky /* detect tda8290 */ 666567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { 66789a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson printk(KERN_WARNING "%s: couldn't read register 0x%02x\n", 668567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab __func__, reg); 669567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab return -ENODEV; 670567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab } 671f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 672567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab if (id == TDA8290_ID) { 673ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (debug) 674f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", 6757e28adb2497f6b873516163e2d29210c11777613Harvey Harrison __func__, i2c_adapter_id(i2c_props->adap), 676f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky i2c_props->addr); 677f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky return 0; 678f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky } 6791f3a4e328549cb85aa032c4ee5dfda7886754154Michael Krufky return -ENODEV; 680f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky} 681f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 682f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufkystatic int tda8295_probe(struct tuner_i2c_props *i2c_props) 683f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky{ 684f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky#define TDA8295_ID 0x8a 68519f8a6c37eead7e93660813c8873ab3e387ccb63Michael Krufky#define TDA8295C2_ID 0x8b 686567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab u8 reg = 0x2f, id; 687567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab struct i2c_msg msg_read[] = { 68889a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = ® }, 68989a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id }, 690567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab }; 691f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 69289a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson /* detect tda8295 */ 693567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) { 69489a8969afa300c202066c23cc5cc9e42eb81967cJarod Wilson printk(KERN_WARNING "%s: couldn't read register 0x%02x\n", 695567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab __func__, reg); 696567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab return -ENODEV; 697567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab } 698f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 699567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab if ((id & 0xfe) == TDA8295_ID) { 700ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (debug) 70119f8a6c37eead7e93660813c8873ab3e387ccb63Michael Krufky printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n", 702567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab __func__, (id == TDA8295_ID) ? 70319f8a6c37eead7e93660813c8873ab3e387ccb63Michael Krufky "tda8295c1" : "tda8295c2", 70419f8a6c37eead7e93660813c8873ab3e387ccb63Michael Krufky i2c_adapter_id(i2c_props->adap), 705f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky i2c_props->addr); 706f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky return 0; 707f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky } 708f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 7091f3a4e328549cb85aa032c4ee5dfda7886754154Michael Krufky return -ENODEV; 710f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky} 711f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 712bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufkystatic struct analog_demod_ops tda8290_ops = { 713c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky .set_params = tda8290_set_params, 7148c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .has_signal = tda8290_has_signal, 7158c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .standby = tda8290_standby, 7168c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .release = tda829x_release, 7178c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .i2c_gate_ctrl = tda8290_i2c_bridge, 7188c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky}; 7198c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 720bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufkystatic struct analog_demod_ops tda8295_ops = { 721c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky .set_params = tda8295_set_params, 7228c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .has_signal = tda8295_has_signal, 7238c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .standby = tda8295_standby, 7248c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .release = tda829x_release, 7258c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .i2c_gate_ctrl = tda8295_i2c_bridge, 7268c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky}; 7278c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 728ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufkystruct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, 729ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky struct i2c_adapter *i2c_adap, u8 i2c_addr, 730ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky struct tda829x_config *cfg) 7315bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 7325bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky struct tda8290_priv *priv = NULL; 733ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky char *name; 7348c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 7355bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); 7365bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (priv == NULL) 737ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky return NULL; 7388c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky fe->analog_demod_priv = priv; 7395bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 740ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->i2c_props.addr = i2c_addr; 741ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->i2c_props.adap = i2c_adap; 7422756665c28a7d2e25d92745195b5171866e12da9Michael Krufky priv->i2c_props.name = "tda829x"; 743d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky if (cfg) 744ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->cfg.config = cfg->lna_cfg; 7455bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 746f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if (tda8290_probe(&priv->i2c_props) == 0) { 7478c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver = TDA8290; 748bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky memcpy(&fe->ops.analog_ops, &tda8290_ops, 749bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky sizeof(struct analog_demod_ops)); 7505bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 7518c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 752f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if (tda8295_probe(&priv->i2c_props) == 0) { 7538c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver = TDA8295; 754bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky memcpy(&fe->ops.analog_ops, &tda8295_ops, 755bc3e5c7fc20d3c09667067878fb7a55dd9fc041dMichael Krufky sizeof(struct analog_demod_ops)); 7565bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 7575bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 7589d700a0696ae241380e8ca833bb5a358620d33f6Mauro Carvalho Chehab if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) { 7599d700a0696ae241380e8ca833bb5a358620d33f6Mauro Carvalho Chehab tda8295_power(fe, 1); 7609d700a0696ae241380e8ca833bb5a358620d33f6Mauro Carvalho Chehab if (tda829x_find_tuner(fe) < 0) 7619d700a0696ae241380e8ca833bb5a358620d33f6Mauro Carvalho Chehab goto fail; 76247ab285a960ac456506297c93322ab13c3522f5aMauro Carvalho Chehab } 7635bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 764ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky switch (priv->ver) { 765c90762799c42df203fc2c9c1a2ac39f154f8facaMichael Krufky case TDA8290: 766c90762799c42df203fc2c9c1a2ac39f154f8facaMichael Krufky name = "tda8290"; 767c90762799c42df203fc2c9c1a2ac39f154f8facaMichael Krufky break; 768c90762799c42df203fc2c9c1a2ac39f154f8facaMichael Krufky case TDA8295: 769c90762799c42df203fc2c9c1a2ac39f154f8facaMichael Krufky name = "tda8295"; 770c90762799c42df203fc2c9c1a2ac39f154f8facaMichael Krufky break; 771ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8290 | TDA8275: 772ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8290+75"; 773ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 774ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8295 | TDA8275: 775ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8295+75"; 776ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 777ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8290 | TDA8275A: 778ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8290+75a"; 779ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 780ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8295 | TDA8275A: 781ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8295+75a"; 782ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 783ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8290 | TDA18271: 784ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8290+18271"; 785ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 786ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8295 | TDA18271: 787ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8295+18271"; 788ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 789ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky default: 790ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky goto fail; 791ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky } 792ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky tuner_info("type set to %s\n", name); 793ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky 7940f2ce9834246519e483e89dbc7225fe1fcbd30a8Michael Krufky fe->ops.analog_ops.info.name = name; 7950f2ce9834246519e483e89dbc7225fe1fcbd30a8Michael Krufky 7968c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (priv->ver & TDA8290) { 797439b72b69e4992e9ec34b74304f0fa95623934ebMichael Krufky if (priv->ver & (TDA8275 | TDA8275A)) 798439b72b69e4992e9ec34b74304f0fa95623934ebMichael Krufky tda8290_init_tuner(fe); 7998c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tda8290_init_if(fe); 8008c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky } else if (priv->ver & TDA8295) 8018c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tda8295_init_if(fe); 8025bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 803ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky return fe; 804fa746aee336fedfe25e6945e5967399966948420Michael Krufky 805fa746aee336fedfe25e6945e5967399966948420Michael Krufkyfail: 8069d700a0696ae241380e8ca833bb5a358620d33f6Mauro Carvalho Chehab memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops)); 8079d700a0696ae241380e8ca833bb5a358620d33f6Mauro Carvalho Chehab 808fa746aee336fedfe25e6945e5967399966948420Michael Krufky tda829x_release(fe); 809ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky return NULL; 8105bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 8118c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael KrufkyEXPORT_SYMBOL_GPL(tda829x_attach); 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 813ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufkyint tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) 81495736034df751631657140aebe677e67d7522867Hartmut Hackmann{ 815910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky struct tuner_i2c_props i2c_props = { 816ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky .adap = i2c_adap, 817ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky .addr = i2c_addr, 818910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky }; 819db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 82044fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char soft_reset[] = { 0x00, 0x00 }; 82144fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char easy_mode_b[] = { 0x01, 0x02 }; 82244fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char easy_mode_g[] = { 0x01, 0x04 }; 82344fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; 82495736034df751631657140aebe677e67d7522867Hartmut Hackmann unsigned char addr_dto_lsb = 0x07; 82595736034df751631657140aebe677e67d7522867Hartmut Hackmann unsigned char data; 826a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky#define PROBE_BUFFER_SIZE 8 827a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky unsigned char buf[PROBE_BUFFER_SIZE]; 828a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky int i; 829a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky 830a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky /* rule out tda9887, which would return the same byte repeatedly */ 831567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&i2c_props, 832567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab soft_reset, 1, buf, PROBE_BUFFER_SIZE); 833a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky for (i = 1; i < PROBE_BUFFER_SIZE; i++) { 834bbe1e0ba527a18e1ddda2eabb9da369e5bcf556eMichael Krufky if (buf[i] != buf[0]) 835bbe1e0ba527a18e1ddda2eabb9da369e5bcf556eMichael Krufky break; 836a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky } 837a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky 838a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky /* all bytes are equal, not a tda829x - probably a tda9887 */ 839a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky if (i == PROBE_BUFFER_SIZE) 840a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky return -ENODEV; 84195736034df751631657140aebe677e67d7522867Hartmut Hackmann 842f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if ((tda8290_probe(&i2c_props) == 0) || 843f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky (tda8295_probe(&i2c_props) == 0)) 844f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky return 0; 845f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 846f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky /* fall back to old probing method */ 847910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); 848910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); 849567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1); 85095736034df751631657140aebe677e67d7522867Hartmut Hackmann if (data == 0) { 851910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); 852910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); 853567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab tuner_i2c_xfer_send_recv(&i2c_props, 854567aba0b7997dad5fe3fb4aeb174ee9018df8c5bMauro Carvalho Chehab &addr_dto_lsb, 1, &data, 1); 85595736034df751631657140aebe677e67d7522867Hartmut Hackmann if (data == 0x7b) { 85695736034df751631657140aebe677e67d7522867Hartmut Hackmann return 0; 85795736034df751631657140aebe677e67d7522867Hartmut Hackmann } 85895736034df751631657140aebe677e67d7522867Hartmut Hackmann } 859910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, restore_9886, 3); 8601f3a4e328549cb85aa032c4ee5dfda7886754154Michael Krufky return -ENODEV; 86195736034df751631657140aebe677e67d7522867Hartmut Hackmann} 862f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael KrufkyEXPORT_SYMBOL_GPL(tda829x_probe); 863910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 8648c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael KrufkyMODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver"); 8655bea1cd3871351d70cc7624af138f8aa68b7be77Michael KrufkyMODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky"); 866910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael KrufkyMODULE_LICENSE("GPL"); 867910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Overrides for Emacs so that we follow Linus's tabbing style. 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * --------------------------------------------------------------------------- 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Local variables: 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * c-basic-offset: 8 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * End: 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 875