aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/rtl2832.c
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2014-02-08 01:50:04 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-03-05 13:41:18 -0500
commit92d20d9fd13a2616294dc804ba3bb78312b84850 (patch)
treec61bb8666a9dca9c0571d608b3cc947d3b5116ea /drivers/media/dvb-frontends/rtl2832.c
parent0db5c800aa460c9f3cb142d65b5893c47ddcecb8 (diff)
[media] rtl2832: implement delayed I2C gate close
Delay possible I2C gate close a little bit in order to see if there is next message coming to tuner in a sequence. Also, export private muxed I2C adapter. That is aimed only for SDR extension module as SDR belongs to same RTL2832 physical I2C bus (it is physically property of RTL2832, whilst it is own kernel module). Signed-off-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/dvb-frontends/rtl2832.c')
-rw-r--r--drivers/media/dvb-frontends/rtl2832.c92
1 files changed, 89 insertions, 3 deletions
diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c
index cfc54388a15e..fdbed35c87fa 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -891,16 +891,65 @@ static void rtl2832_release(struct dvb_frontend *fe)
891 struct rtl2832_priv *priv = fe->demodulator_priv; 891 struct rtl2832_priv *priv = fe->demodulator_priv;
892 892
893 dev_dbg(&priv->i2c->dev, "%s:\n", __func__); 893 dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
894 cancel_delayed_work_sync(&priv->i2c_gate_work);
894 i2c_del_mux_adapter(priv->i2c_adapter_tuner); 895 i2c_del_mux_adapter(priv->i2c_adapter_tuner);
895 i2c_del_mux_adapter(priv->i2c_adapter); 896 i2c_del_mux_adapter(priv->i2c_adapter);
896 kfree(priv); 897 kfree(priv);
897} 898}
898 899
900/*
901 * Delay mechanism to avoid unneeded I2C gate open / close. Gate close is
902 * delayed here a little bit in order to see if there is sequence of I2C
903 * messages sent to same I2C bus.
904 * We must use unlocked version of __i2c_transfer() in order to avoid deadlock
905 * as lock is already taken by calling muxed i2c_transfer().
906 */
907static void rtl2832_i2c_gate_work(struct work_struct *work)
908{
909 struct rtl2832_priv *priv = container_of(work,
910 struct rtl2832_priv, i2c_gate_work.work);
911 struct i2c_adapter *adap = priv->i2c;
912 int ret;
913 u8 buf[2];
914 struct i2c_msg msg[1] = {
915 {
916 .addr = priv->cfg.i2c_addr,
917 .flags = 0,
918 .len = sizeof(buf),
919 .buf = buf,
920 }
921 };
922
923 /* select reg bank 1 */
924 buf[0] = 0x00;
925 buf[1] = 0x01;
926 ret = __i2c_transfer(adap, msg, 1);
927 if (ret != 1)
928 goto err;
929
930 priv->page = 1;
931
932 /* close I2C repeater gate */
933 buf[0] = 0x01;
934 buf[1] = 0x10;
935 ret = __i2c_transfer(adap, msg, 1);
936 if (ret != 1)
937 goto err;
938
939 priv->i2c_gate_state = 0;
940
941 return;
942err:
943 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
944
945 return;
946}
947
899static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id) 948static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
900{ 949{
901 struct rtl2832_priv *priv = mux_priv; 950 struct rtl2832_priv *priv = mux_priv;
902 int ret; 951 int ret;
903 u8 buf[2]; 952 u8 buf[2], val;
904 struct i2c_msg msg[1] = { 953 struct i2c_msg msg[1] = {
905 { 954 {
906 .addr = priv->cfg.i2c_addr, 955 .addr = priv->cfg.i2c_addr,
@@ -909,6 +958,22 @@ static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
909 .buf = buf, 958 .buf = buf,
910 } 959 }
911 }; 960 };
961 struct i2c_msg msg_rd[2] = {
962 {
963 .addr = priv->cfg.i2c_addr,
964 .flags = 0,
965 .len = 1,
966 .buf = "\x01",
967 }, {
968 .addr = priv->cfg.i2c_addr,
969 .flags = I2C_M_RD,
970 .len = 1,
971 .buf = &val,
972 }
973 };
974
975 /* terminate possible gate closing */
976 cancel_delayed_work_sync(&priv->i2c_gate_work);
912 977
913 if (priv->i2c_gate_state == chan_id) 978 if (priv->i2c_gate_state == chan_id)
914 return 0; 979 return 0;
@@ -916,13 +981,17 @@ static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
916 /* select reg bank 1 */ 981 /* select reg bank 1 */
917 buf[0] = 0x00; 982 buf[0] = 0x00;
918 buf[1] = 0x01; 983 buf[1] = 0x01;
919
920 ret = __i2c_transfer(adap, msg, 1); 984 ret = __i2c_transfer(adap, msg, 1);
921 if (ret != 1) 985 if (ret != 1)
922 goto err; 986 goto err;
923 987
924 priv->page = 1; 988 priv->page = 1;
925 989
990 /* we must read that register, otherwise there will be errors */
991 ret = __i2c_transfer(adap, msg_rd, 2);
992 if (ret != 2)
993 goto err;
994
926 /* open or close I2C repeater gate */ 995 /* open or close I2C repeater gate */
927 buf[0] = 0x01; 996 buf[0] = 0x01;
928 if (chan_id == 1) 997 if (chan_id == 1)
@@ -939,9 +1008,18 @@ static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 chan_id)
939 return 0; 1008 return 0;
940err: 1009err:
941 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret); 1010 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
1011
942 return -EREMOTEIO; 1012 return -EREMOTEIO;
943} 1013}
944 1014
1015static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv,
1016 u32 chan_id)
1017{
1018 struct rtl2832_priv *priv = mux_priv;
1019 schedule_delayed_work(&priv->i2c_gate_work, usecs_to_jiffies(100));
1020 return 0;
1021}
1022
945struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe) 1023struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe)
946{ 1024{
947 struct rtl2832_priv *priv = fe->demodulator_priv; 1025 struct rtl2832_priv *priv = fe->demodulator_priv;
@@ -949,6 +1027,13 @@ struct i2c_adapter *rtl2832_get_i2c_adapter(struct dvb_frontend *fe)
949} 1027}
950EXPORT_SYMBOL(rtl2832_get_i2c_adapter); 1028EXPORT_SYMBOL(rtl2832_get_i2c_adapter);
951 1029
1030struct i2c_adapter *rtl2832_get_private_i2c_adapter(struct dvb_frontend *fe)
1031{
1032 struct rtl2832_priv *priv = fe->demodulator_priv;
1033 return priv->i2c_adapter;
1034}
1035EXPORT_SYMBOL(rtl2832_get_private_i2c_adapter);
1036
952struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg, 1037struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
953 struct i2c_adapter *i2c) 1038 struct i2c_adapter *i2c)
954{ 1039{
@@ -967,6 +1052,7 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
967 priv->i2c = i2c; 1052 priv->i2c = i2c;
968 priv->tuner = cfg->tuner; 1053 priv->tuner = cfg->tuner;
969 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config)); 1054 memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
1055 INIT_DELAYED_WORK(&priv->i2c_gate_work, rtl2832_i2c_gate_work);
970 1056
971 /* create muxed i2c adapter for demod itself */ 1057 /* create muxed i2c adapter for demod itself */
972 priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0, 1058 priv->i2c_adapter = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 0, 0, 0,
@@ -981,7 +1067,7 @@ struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
981 1067
982 /* create muxed i2c adapter for demod tuner bus */ 1068 /* create muxed i2c adapter for demod tuner bus */
983 priv->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, priv, 1069 priv->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, &i2c->dev, priv,
984 0, 1, 0, rtl2832_select, NULL); 1070 0, 1, 0, rtl2832_select, rtl2832_deselect);
985 if (priv->i2c_adapter_tuner == NULL) 1071 if (priv->i2c_adapter_tuner == NULL)
986 goto err; 1072 goto err;
987 1073