tda8290.c revision ab1660503ac3af7febfcf987648509b484d4feda
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> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 25ffbb807c1362a2b64b473c0e093c496a4c7de4bbMichael Krufky#include <linux/videodev.h> 26ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky#include "tuner-driver.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 369dd659de9fbd1687c6175053c6453db5b932f152Hans Verkuil#define PREFIX "tda8290" 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ---------------------------------------------------------------------- */ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufkystruct tda8290_priv { 41db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky struct tuner_i2c_props i2c_props; 42db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 43b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky unsigned char tda8290_easy_mode; 44746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 45b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky unsigned char tda827x_addr; 468c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 478c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky unsigned char ver; 488c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8290 1 498c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8295 2 508c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8275 4 518c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA8275A 8 528c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky#define TDA18271 16 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 54746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky struct tda827x_config cfg; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufkystatic int tda8290_i2c_bridge(struct dvb_frontend *fe, int close) 60de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann{ 614e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 62db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 63de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char enable[2] = { 0x21, 0xC0 }; 640157a9cc727dec90a7d60ad254eb899a775685a9Hartmut Hackmann unsigned char disable[2] = { 0x21, 0x00 }; 65de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char *msg; 66a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 67a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky if (close) { 68de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg = enable; 69db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 70de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* let the bridge stabilize */ 71de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(20); 72de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } else { 73de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg = disable; 74db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 75de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 76a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 77a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky return 0; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 80a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufkystatic int tda8295_i2c_bridge(struct dvb_frontend *fe, int close) 815bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 824e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 835bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 845bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char enable[2] = { 0x45, 0xc1 }; 855bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char disable[2] = { 0x46, 0x00 }; 865bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[3] = { 0x45, 0x01, 0x00 }; 875bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char *msg; 88a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 895bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (close) { 905bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msg = enable; 915bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 925bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky /* let the bridge stabilize */ 935bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(20); 945bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } else { 955bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msg = disable; 965bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 1); 975bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &msg[1], 1); 985bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 995bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[2] = msg[1]; 1005bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[2] &= ~0x04; 1015bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 3); 1025bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(5); 1035bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 1045bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msg[1] |= 0x04; 1055bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, msg, 2); 1065bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 107a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky 108a72dd305f99f6c6e4eff01478ae53fc80ce98fb1Michael Krufky return 0; 1095bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 1105bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 111de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 112de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 113c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufkystatic void set_audio(struct dvb_frontend *fe, 114c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky struct analog_parameters *params) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1164e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 117910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky char* mode; 118910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 119c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky if (params->std & V4L2_STD_MN) { 120910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x01; 121910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "MN"; 122c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_B) { 123910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x02; 124910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "B"; 125c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_GH) { 126910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x04; 127910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "GH"; 128c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_PAL_I) { 129910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x08; 130910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "I"; 131c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_DK) { 132910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x10; 133910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "DK"; 134c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_SECAM_L) { 135910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x20; 136910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "L"; 137c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky } else if (params->std & V4L2_STD_SECAM_LC) { 138910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x40; 139910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "LC"; 140910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky } else { 141910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky priv->tda8290_easy_mode = 0x10; 142910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky mode = "xx"; 143910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky } 144910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 1458c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_dbg("setting tda829x to system %s\n", mode); 146910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky} 147910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 148c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufkystatic void tda8290_set_params(struct dvb_frontend *fe, 149c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky struct analog_parameters *params) 150910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky{ 1514e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 1524e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky 153de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char soft_reset[] = { 0x00, 0x00 }; 154b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; 155de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char expert_mode[] = { 0x01, 0x80 }; 1560157a9cc727dec90a7d60ad254eb899a775685a9Hartmut Hackmann unsigned char agc_out_on[] = { 0x02, 0x00 }; 157de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char gainset_off[] = { 0x28, 0x14 }; 158de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char if_agc_spd[] = { 0x0f, 0x88 }; 159de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_head_6[] = { 0x05, 0x04 }; 160de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_head_9[] = { 0x05, 0x02 }; 161de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_head_12[] = { 0x05, 0x01 }; 162de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char pll_bw_nom[] = { 0x0d, 0x47 }; 163de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char pll_bw_low[] = { 0x0d, 0x27 }; 164de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char gainset_2[] = { 0x28, 0x64 }; 165de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char agc_rst_on[] = { 0x0e, 0x0b }; 166de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char agc_rst_off[] = { 0x0e, 0x09 }; 167de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char if_agc_set[] = { 0x0f, 0x81 }; 168de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char addr_adc_sat = 0x1a; 169de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char addr_agc_stat = 0x1d; 170de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char addr_pll_stat = 0x1b; 171de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char adc_sat, agc_stat, 1729a741ec9b87ac13f13a1dfcb05979d7c785d0755Nickolay V. Shmyrev pll_stat; 17358ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann int i; 174de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 175c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky set_audio(fe, params); 176910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 177ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (priv->cfg.config) 178ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky tuner_dbg("tda827xa config is 0x%02x\n", *priv->cfg.config); 179db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); 180db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); 181db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); 182de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(1); 183de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 184b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky expert_mode[1] = priv->tda8290_easy_mode + 0x80; 185db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2); 186db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2); 187db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2); 188b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky if (priv->tda8290_easy_mode & 0x60) 189db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2); 190de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann else 191db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); 192db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); 193de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 1944e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 1); 195746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 1964e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (fe->ops.tuner_ops.set_analog_params) 197c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky fe->ops.tuner_ops.set_analog_params(fe, params); 198746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 19958ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann for (i = 0; i < 3; i++) { 200db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); 201db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); 20258ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann if (pll_stat & 0x80) { 203db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); 204db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); 205db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); 206db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); 20758ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat); 20858ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann break; 20958ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann } else { 21058ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann tuner_dbg("tda8290 not locked, no signal?\n"); 21158ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann msleep(100); 21258ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann } 21358ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann } 214de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* adjust headroom resp. gain */ 2154ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) { 2164ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n", 2174ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann agc_stat, adc_sat, pll_stat & 0x80); 218db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2); 219de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(100); 220db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); 221db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); 222db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); 223db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); 224de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if ((agc_stat > 115) || !(pll_stat & 0x80)) { 2254ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", 2264ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann agc_stat, pll_stat & 0x80); 227746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky if (priv->cfg.agcf) 2284e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky priv->cfg.agcf(fe); 229de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(100); 230db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); 231db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); 232db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); 233db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); 234de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if((agc_stat > 115) || !(pll_stat & 0x80)) { 235de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat); 236db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2); 237db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2); 238de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(100); 239de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 240de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 241de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 243de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* l/ l' deadlock? */ 244b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky if(priv->tda8290_easy_mode & 0x60) { 245db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_adc_sat, 1); 246db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &adc_sat, 1); 247db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); 248db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); 249de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if ((adc_sat > 20) || !(pll_stat & 0x80)) { 2504ac95af9a0bdc33f18e6a7532ac5319b2d4ab8c2Hartmut Hackmann tuner_dbg("trying to resolve SECAM L deadlock\n"); 251db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2); 252de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msleep(40); 253db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2); 254de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 255de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 256586b0cab2516640fec4dffc3049c4d8bca188f89Mauro Carvalho Chehab 2574e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 0); 258db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 262de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 2634e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_power(struct dvb_frontend *fe, int enable) 2645bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 2654e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 2665bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */ 2675bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2685bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); 2695bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); 2705bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2715bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) 2725bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x01; 2735bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 2745bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x03; 2755bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2765bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 2775bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 2785bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2794e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable) 2805bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 2814e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 2825bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x01, 0x00 }; 2835bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2845bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); 2855bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); 2865bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2875bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) 2885bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */ 2895bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 2905bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] = 0x00; /* reset active bit */ 2915bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2925bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 2935bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 2945bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 2954e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_set_video_std(struct dvb_frontend *fe) 2965bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 2974e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 2985bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x00, priv->tda8290_easy_mode }; 2995bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3005bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 3015bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3024e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_easy_mode(fe, 1); 3035bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(20); 3044e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_easy_mode(fe, 0); 3055bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3065bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3075bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky/*---------------------------------------------------------------------*/ 3085bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3094e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_agc1_out(struct dvb_frontend *fe, int enable) 3105bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3114e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3125bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */ 3135bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3145bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &buf[0], 1); 3155bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &buf[1], 1); 3165bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3175bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) 3185bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] &= ~0x40; 3195bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 3205bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky buf[1] |= 0x40; 3215bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3225bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); 3235bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3245bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3254e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_agc2_out(struct dvb_frontend *fe, int enable) 3265bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3274e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3285bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char set_gpio_cf[] = { 0x44, 0x00 }; 3295bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char set_gpio_val[] = { 0x46, 0x00 }; 3305bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3315bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_cf[0], 1); 3325bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_cf[1], 1); 3335bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &set_gpio_val[0], 1); 3345bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &set_gpio_val[1], 1); 3355bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3365bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */ 3375bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3385bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (enable) { 3395bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */ 3405bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */ 3415bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 3425bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2); 3435bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2); 3445bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3455bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3464e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic int tda8295_has_signal(struct dvb_frontend *fe) 3475bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3484e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3495bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3505bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char hvpll_stat = 0x26; 3515bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char ret; 3525bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3535bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &hvpll_stat, 1); 3545bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &ret, 1); 3555bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky return (ret & 0x01) ? 65535 : 0; 3565bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3575bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3585bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky/*---------------------------------------------------------------------*/ 3595bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 360c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufkystatic void tda8295_set_params(struct dvb_frontend *fe, 361c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky struct analog_parameters *params) 3625bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 3634e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 3645bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3655bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky unsigned char blanking_mode[] = { 0x1d, 0x00 }; 3665bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 367c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky set_audio(fe, params); 3685bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 369c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky tuner_dbg("%s: freq = %d\n", __FUNCTION__, params->frequency); 3705bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3714e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_power(fe, 1); 3724e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc1_out(fe, 1); 3735bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3745bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, &blanking_mode[0], 1); 3755bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &blanking_mode[1], 1); 3765bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3774e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_video_std(fe); 3785bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3795bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky blanking_mode[1] = 0x03; 3805bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2); 3815bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky msleep(20); 3825bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3834e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_i2c_bridge(fe, 1); 3845bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3854e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (fe->ops.tuner_ops.set_analog_params) 386c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky fe->ops.tuner_ops.set_analog_params(fe, params); 3875bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3885bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (priv->cfg.agcf) 3894e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky priv->cfg.agcf(fe); 3905bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3914e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (tda8295_has_signal(fe)) 3925bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_dbg("tda8295 is locked\n"); 3935bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky else 3945bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_dbg("tda8295 not locked, no signal?\n"); 3955bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3964e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_i2c_bridge(fe, 0); 3975bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 3985bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 3995bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky/*---------------------------------------------------------------------*/ 4005bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4014e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic int tda8290_has_signal(struct dvb_frontend *fe) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4034e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 405910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky unsigned char i2c_get_afc[1] = { 0x1B }; 406910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky unsigned char afc = 0; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 408910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc)); 409910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1); 410746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky return (afc & 0x80)? 65535:0; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 413de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 414de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4154e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8290_standby(struct dvb_frontend *fe) 416793cf9e6a54c698e109a599c8b8e303658fcaae6Mauro Carvalho Chehab{ 4174e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 4184e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky 419de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char cb1[] = { 0x30, 0xD0 }; 420de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char tda8290_standby[] = { 0x00, 0x02 }; 4210157a9cc727dec90a7d60ad254eb899a775685a9Hartmut Hackmann unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; 422b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; 423de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4244e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 1); 4258c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (priv->ver & TDA8275A) 426de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann cb1[1] = 0x90; 427db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky i2c_transfer(priv->i2c_props.adap, &msg, 1); 4284e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 0); 429db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); 430db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); 431793cf9e6a54c698e109a599c8b8e303658fcaae6Mauro Carvalho Chehab} 432793cf9e6a54c698e109a599c8b8e303658fcaae6Mauro Carvalho Chehab 4334e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_standby(struct dvb_frontend *fe) 4345bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 4354e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */ 4365bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4374e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_power(fe, 0); 4385bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 4395bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4404e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8290_init_if(struct dvb_frontend *fe) 441de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann{ 4424e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 443db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 444de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char set_VS[] = { 0x30, 0x6F }; 44558ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann unsigned char set_GP00_CF[] = { 0x20, 0x01 }; 446de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char set_GP01_CF[] = { 0x20, 0x0B }; 447de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 448ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if ((priv->cfg.config) && 449ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky ((*priv->cfg.config == 1) || (*priv->cfg.config == 2))) 450db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); 45158ef4f924cf2824ae198b1fec3eea1e4059a021cHartmut Hackmann else 452db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); 453db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2); 454de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann} 455de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4564e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8295_init_if(struct dvb_frontend *fe) 4575bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 4584e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 4595bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4605bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_adc_ctl[] = { 0x33, 0x14 }; 4615bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_adc_ctl2[] = { 0x34, 0x00 }; 4625bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg6[] = { 0x3e, 0x63 }; 4635bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg0[] = { 0x38, 0x23 }; 4645bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg7[] = { 0x3f, 0x01 }; 4655bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_pll_reg10[] = { 0x42, 0x61 }; 4665bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky static unsigned char set_gpio_reg0[] = { 0x44, 0x0b }; 4675bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4684e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_power(fe, 1); 4695bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4704e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_easy_mode(fe, 0); 4714e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_set_video_std(fe); 4725bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4735bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2); 4745bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2); 4755bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2); 4765bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2); 4775bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2); 4785bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2); 4795bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2); 4805bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4814e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc1_out(fe, 0); 4824e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8295_agc2_out(fe, 0); 4835bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 4845bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 4854e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda8290_init_tuner(struct dvb_frontend *fe) 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4874e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 488de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, 4899a741ec9b87ac13f13a1dfcb05979d7c785d0755Nickolay V. Shmyrev 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; 490de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, 4919a741ec9b87ac13f13a1dfcb05979d7c785d0755Nickolay V. Shmyrev 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b }; 492b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, 493c2f6f9d866d3ea25eebe32c6c51e47e5141669cfRicardo Cerqueira .buf=tda8275_init, .len = 14}; 4948c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (priv->ver & TDA8275A) 495de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.buf = tda8275a_init; 496de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 4974e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 1); 498db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky i2c_transfer(priv->i2c_props.adap, &msg, 1); 4994e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky tda8290_i2c_bridge(fe, 0); 500de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann} 501de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 502de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann/*---------------------------------------------------------------------*/ 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5044e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufkystatic void tda829x_release(struct dvb_frontend *fe) 505024cf53089f7c8e58934407f07ca2a7b5bed3b06Michael Krufky{ 5064e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky if (fe->ops.tuner_ops.release) 5074e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky fe->ops.tuner_ops.release(fe); 508024cf53089f7c8e58934407f07ca2a7b5bed3b06Michael Krufky 5094e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky kfree(fe->analog_demod_priv); 5104e9154b8a77d0f0f8f06857162823905612a50d7Michael Krufky fe->analog_demod_priv = NULL; 511910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky} 512910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 5138c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufkystatic int tda829x_find_tuner(struct dvb_frontend *fe) 514de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann{ 5158c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky struct tda8290_priv *priv = fe->analog_demod_priv; 5168c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky struct analog_tuner_ops *ops = fe->ops.analog_demod_ops; 517de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann int i, ret, tuners_found; 518de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann u32 tuner_addrs; 5198c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky u8 data; 5208c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; 521de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 5228c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (NULL == ops) 5238c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky return -EINVAL; 524746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 5258c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky ops->i2c_gate_ctrl(fe, 1); 526db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 527de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* probe for tuner chip */ 528de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuners_found = 0; 529de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = 0; 5308c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky for (i = 0x60; i <= 0x63; i++) { 531de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.addr = i; 532db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 533de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if (ret == 1) { 534de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuners_found++; 535de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = (tuner_addrs << 8) + i; 536de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 537de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 538de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann /* if there is more than one tuner, we expect the right one is 539de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann behind the bridge and we choose the highest address that doesn't 540de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann give a response now 541de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann */ 5428c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 5438c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky ops->i2c_gate_ctrl(fe, 0); 5448c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 5458c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (tuners_found > 1) 546de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann for (i = 0; i < tuners_found; i++) { 547de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.addr = tuner_addrs & 0xff; 548db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 5498c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (ret == 1) 550de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = tuner_addrs >> 8; 551de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann else 552de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann break; 553de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 5548c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 555de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann if (tuner_addrs == 0) { 5568c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_addrs = 0x60; 5578c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_info("could not clearly identify tuner address, " 5588c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky "defaulting to %x\n", tuner_addrs); 559de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } else { 560de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann tuner_addrs = tuner_addrs & 0xff; 561910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_info("setting tuner address to %x\n", tuner_addrs); 562de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 563b208319993ceff7ebfcc6bb914fe94d29e48a891Michael Krufky priv->tda827x_addr = tuner_addrs; 564de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann msg.addr = tuner_addrs; 565de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann 5668c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky ops->i2c_gate_ctrl(fe, 1); 567db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 568910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 5698c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (ret != 1) { 5708c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tuner_warn("tuner access failed!\n"); 5718c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky return -EREMOTEIO; 572de48eebce8b63dbae7272ee80f4fe0eaddb61278Hartmut Hackmann } 573746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 5748c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (data == 0x83) { 5758c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver |= TDA18271; 5766881647cce09931f3d787ab83b5250436427ceb9Michael Krufky tda18271_attach(fe, priv->tda827x_addr, 5778c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->i2c_props.adap); 5788c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky } else { 5798c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if ((data & 0x3c) == 0) 5808c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver |= TDA8275; 5818c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky else 5828c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver |= TDA8275A; 5837fd8b263678ab8430b49c99976ade681f8a78439Michael Krufky 5846881647cce09931f3d787ab83b5250436427ceb9Michael Krufky tda827x_attach(fe, priv->tda827x_addr, 5858c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->i2c_props.adap, &priv->cfg); 5868c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky } 5876881647cce09931f3d787ab83b5250436427ceb9Michael Krufky if (fe->ops.tuner_ops.init) 5886881647cce09931f3d787ab83b5250436427ceb9Michael Krufky fe->ops.tuner_ops.init(fe); 58963c254805e38bad4c64b5f5b0e135a2a357fa0bfMichael Krufky 5906881647cce09931f3d787ab83b5250436427ceb9Michael Krufky if (fe->ops.tuner_ops.sleep) 5916881647cce09931f3d787ab83b5250436427ceb9Michael Krufky fe->ops.tuner_ops.sleep(fe); 59263c254805e38bad4c64b5f5b0e135a2a357fa0bfMichael Krufky 5938c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky ops->i2c_gate_ctrl(fe, 0); 594746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky 595746d9732dbd5b95c3ba36230e2814fa2c391a311Michael Krufky return 0; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5975bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 598f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufkystatic int tda8290_probe(struct tuner_i2c_props *i2c_props) 599f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky{ 600f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky#define TDA8290_ID 0x89 601f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky unsigned char tda8290_id[] = { 0x1f, 0x00 }; 602f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 603f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky /* detect tda8290 */ 604f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky tuner_i2c_xfer_send(i2c_props, &tda8290_id[0], 1); 605f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky tuner_i2c_xfer_recv(i2c_props, &tda8290_id[1], 1); 606f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 607f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if (tda8290_id[1] == TDA8290_ID) { 608ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (debug) 609f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n", 610f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky __FUNCTION__, i2c_adapter_id(i2c_props->adap), 611f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky i2c_props->addr); 612f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky return 0; 613f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky } 614f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 6151f3a4e328549cb85aa032c4ee5dfda7886754154Michael Krufky return -ENODEV; 616f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky} 617f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 618f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufkystatic int tda8295_probe(struct tuner_i2c_props *i2c_props) 619f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky{ 620f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky#define TDA8295_ID 0x8a 621f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky unsigned char tda8295_id[] = { 0x2f, 0x00 }; 622f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 623f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky /* detect tda8295 */ 624f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky tuner_i2c_xfer_send(i2c_props, &tda8295_id[0], 1); 625f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky tuner_i2c_xfer_recv(i2c_props, &tda8295_id[1], 1); 626f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 627f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if (tda8295_id[1] == TDA8295_ID) { 628ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (debug) 629f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky printk(KERN_DEBUG "%s: tda8295 detected @ %d-%04x\n", 630f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky __FUNCTION__, i2c_adapter_id(i2c_props->adap), 631f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky i2c_props->addr); 632f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky return 0; 633f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky } 634f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 6351f3a4e328549cb85aa032c4ee5dfda7886754154Michael Krufky return -ENODEV; 636f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky} 637f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 6388c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufkystatic struct analog_tuner_ops tda8290_tuner_ops = { 639c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky .set_params = tda8290_set_params, 6408c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .has_signal = tda8290_has_signal, 6418c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .standby = tda8290_standby, 6428c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .release = tda829x_release, 6438c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .i2c_gate_ctrl = tda8290_i2c_bridge, 6448c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky}; 6458c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 6468c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufkystatic struct analog_tuner_ops tda8295_tuner_ops = { 647c7919d520f4c9a064ae14bc4dd170c4c12ead2afMichael Krufky .set_params = tda8295_set_params, 6488c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .has_signal = tda8295_has_signal, 6498c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .standby = tda8295_standby, 6508c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .release = tda829x_release, 6518c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky .i2c_gate_ctrl = tda8295_i2c_bridge, 6528c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky}; 6538c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 654ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufkystruct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, 655ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky struct i2c_adapter *i2c_adap, u8 i2c_addr, 656ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky struct tda829x_config *cfg) 6575bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky{ 6585bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky struct tda8290_priv *priv = NULL; 659ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky char *name; 6608c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 6615bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); 6625bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky if (priv == NULL) 663ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky return NULL; 6648c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky fe->analog_demod_priv = priv; 6655bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 666ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->i2c_props.addr = i2c_addr; 667ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->i2c_props.adap = i2c_adap; 668ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky if (cfg) { 669ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->cfg.config = cfg->lna_cfg; 670ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky priv->cfg.tuner_callback = cfg->tuner_callback; 671ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky } 6725bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 673f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if (tda8290_probe(&priv->i2c_props) == 0) { 6748c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver = TDA8290; 6758c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky fe->ops.analog_demod_ops = &tda8290_tuner_ops; 6765bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 6778c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky 678f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if (tda8295_probe(&priv->i2c_props) == 0) { 6798c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky priv->ver = TDA8295; 6808c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky fe->ops.analog_demod_ops = &tda8295_tuner_ops; 6815bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky } 6825bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 6838c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (tda829x_find_tuner(fe) < 0) 684fa746aee336fedfe25e6945e5967399966948420Michael Krufky goto fail; 6855bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 686ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky switch (priv->ver) { 687ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8290 | TDA8275: 688ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8290+75"; 689ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 690ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8295 | TDA8275: 691ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8295+75"; 692ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 693ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8290 | TDA8275A: 694ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8290+75a"; 695ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 696ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8295 | TDA8275A: 697ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8295+75a"; 698ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 699ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8290 | TDA18271: 700ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8290+18271"; 701ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 702ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky case TDA8295 | TDA18271: 703ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky name = "tda8295+18271"; 704ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky break; 705ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky default: 706ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky goto fail; 707ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky } 708ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky tuner_info("type set to %s\n", name); 709ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky 7108c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky if (priv->ver & TDA8290) { 7118c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tda8290_init_tuner(fe); 7128c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tda8290_init_if(fe); 7138c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky } else if (priv->ver & TDA8295) 7148c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael Krufky tda8295_init_if(fe); 7155bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky 716ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky return fe; 717fa746aee336fedfe25e6945e5967399966948420Michael Krufky 718fa746aee336fedfe25e6945e5967399966948420Michael Krufkyfail: 719fa746aee336fedfe25e6945e5967399966948420Michael Krufky tda829x_release(fe); 720fa746aee336fedfe25e6945e5967399966948420Michael Krufky fe->ops.analog_demod_ops = NULL; 721ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky return NULL; 7225bea1cd3871351d70cc7624af138f8aa68b7be77Michael Krufky} 7238c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael KrufkyEXPORT_SYMBOL_GPL(tda829x_attach); 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 725ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufkyint tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr) 72695736034df751631657140aebe677e67d7522867Hartmut Hackmann{ 727910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky struct tuner_i2c_props i2c_props = { 728ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky .adap = i2c_adap, 729ab1660503ac3af7febfcf987648509b484d4fedaMichael Krufky .addr = i2c_addr, 730910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky }; 731db8a695658cda21eacfa2a5e3b15e8964bfb93efMichael Krufky 73244fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char soft_reset[] = { 0x00, 0x00 }; 73344fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char easy_mode_b[] = { 0x01, 0x02 }; 73444fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char easy_mode_g[] = { 0x01, 0x04 }; 73544fd06fa9002c42b367c152594cc95b7632c081dHartmut Hackmann unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 }; 73695736034df751631657140aebe677e67d7522867Hartmut Hackmann unsigned char addr_dto_lsb = 0x07; 73795736034df751631657140aebe677e67d7522867Hartmut Hackmann unsigned char data; 738a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky#define PROBE_BUFFER_SIZE 8 739a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky unsigned char buf[PROBE_BUFFER_SIZE]; 740a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky int i; 741a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky 742a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky /* rule out tda9887, which would return the same byte repeatedly */ 743a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky tuner_i2c_xfer_send(&i2c_props, soft_reset, 1); 744a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky tuner_i2c_xfer_recv(&i2c_props, buf, PROBE_BUFFER_SIZE); 745a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky for (i = 1; i < PROBE_BUFFER_SIZE; i++) { 746bbe1e0ba527a18e1ddda2eabb9da369e5bcf556eMichael Krufky if (buf[i] != buf[0]) 747bbe1e0ba527a18e1ddda2eabb9da369e5bcf556eMichael Krufky break; 748a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky } 749a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky 750a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky /* all bytes are equal, not a tda829x - probably a tda9887 */ 751a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky if (i == PROBE_BUFFER_SIZE) 752a818e1c8f7fcb42866a8630c508caddaa8edb331Michael Krufky return -ENODEV; 75395736034df751631657140aebe677e67d7522867Hartmut Hackmann 754f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky if ((tda8290_probe(&i2c_props) == 0) || 755f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky (tda8295_probe(&i2c_props) == 0)) 756f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky return 0; 757f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky 758f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael Krufky /* fall back to old probing method */ 759910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2); 760910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); 761910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); 762910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_recv(&i2c_props, &data, 1); 76395736034df751631657140aebe677e67d7522867Hartmut Hackmann if (data == 0) { 764910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2); 765910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, soft_reset, 2); 766910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1); 767910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_recv(&i2c_props, &data, 1); 76895736034df751631657140aebe677e67d7522867Hartmut Hackmann if (data == 0x7b) { 76995736034df751631657140aebe677e67d7522867Hartmut Hackmann return 0; 77095736034df751631657140aebe677e67d7522867Hartmut Hackmann } 77195736034df751631657140aebe677e67d7522867Hartmut Hackmann } 772910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky tuner_i2c_xfer_send(&i2c_props, restore_9886, 3); 7731f3a4e328549cb85aa032c4ee5dfda7886754154Michael Krufky return -ENODEV; 77495736034df751631657140aebe677e67d7522867Hartmut Hackmann} 775f1f32849d65ab1eacfedbabb624876ac06c1af9fMichael KrufkyEXPORT_SYMBOL_GPL(tda829x_probe); 776910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 7778c125f2ceb3ec1ba01e96fffd8558ef163b40fe8Michael KrufkyMODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver"); 7785bea1cd3871351d70cc7624af138f8aa68b7be77Michael KrufkyMODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky"); 779910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael KrufkyMODULE_LICENSE("GPL"); 780910bb3e3c5a5d8ed5028846728efc6a375d200ebMichael Krufky 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Overrides for Emacs so that we follow Linus's tabbing style. 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * --------------------------------------------------------------------------- 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Local variables: 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * c-basic-offset: 8 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * End: 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 788