Commit 47cc5b78 authored by Chris Pascoe's avatar Chris Pascoe Committed by Mauro Carvalho Chehab

V4L/DVB (6631): xc2028: eliminate i2c macro side-effects

The I2C macros have side effects and send_seq could cause a return from
a function with a mutex held.  Change them to behave like real functions.
Signed-off-by: default avatarChris Pascoe <c.pascoe@itee.uq.edu.au>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 794604c3
...@@ -83,31 +83,35 @@ struct xc2028_data { ...@@ -83,31 +83,35 @@ struct xc2028_data {
struct mutex lock; struct mutex lock;
}; };
#define i2c_send(rc, priv, buf, size) do { \ #define i2c_send(priv, buf, size) ({ \
rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \ int _rc; \
if (size != rc) \ _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \
tuner_err("i2c output error: rc = %d (should be %d)\n", \ if (size != _rc) \
rc, (int)size); \ tuner_info("i2c output error: rc = %d (should be %d)\n",\
} while (0) _rc, (int)size); \
_rc; \
#define i2c_rcv(rc, priv, buf, size) do { \ })
rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \
if (size != rc) \ #define i2c_rcv(priv, buf, size) ({ \
int _rc; \
_rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \
if (size != _rc) \
tuner_err("i2c input error: rc = %d (should be %d)\n", \ tuner_err("i2c input error: rc = %d (should be %d)\n", \
rc, (int)size); \ _rc, (int)size); \
} while (0) _rc; \
})
#define send_seq(priv, data...) do { \ #define send_seq(priv, data...) ({ \
int rc; \
static u8 _val[] = data; \ static u8 _val[] = data; \
int _rc; \
if (sizeof(_val) != \ if (sizeof(_val) != \
(rc = tuner_i2c_xfer_send(&priv->i2c_props, \ (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \
_val, sizeof(_val)))) { \ _val, sizeof(_val)))) { \
tuner_err("Error on line %d: %d\n", __LINE__, rc); \ tuner_err("Error on line %d: %d\n", __LINE__, _rc); \
return -EINVAL; \ } else \
} \ msleep(10); \
msleep(10); \ _rc; \
} while (0) })
static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg) static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
{ {
...@@ -119,11 +123,11 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg) ...@@ -119,11 +123,11 @@ static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
buf[0] = reg>>8; buf[0] = reg>>8;
buf[1] = (unsigned char) reg; buf[1] = (unsigned char) reg;
i2c_send(rc, priv, buf, 2); rc = i2c_send(priv, buf, 2);
if (rc < 0) if (rc < 0)
return rc; return rc;
i2c_rcv(rc, priv, buf, 2); rc = i2c_rcv(priv, buf, 2);
if (rc < 0) if (rc < 0)
return rc; return rc;
...@@ -505,7 +509,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type, ...@@ -505,7 +509,7 @@ static int load_firmware(struct dvb_frontend *fe, unsigned int type,
memcpy(buf + 1, p, len); memcpy(buf + 1, p, len);
i2c_send(rc, priv, buf, len + 1); rc = i2c_send(priv, buf, len + 1);
if (rc < 0) { if (rc < 0) {
tuner_err("%d returned from send\n", rc); tuner_err("%d returned from send\n", rc);
return -EINVAL; return -EINVAL;
...@@ -541,15 +545,20 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type, ...@@ -541,15 +545,20 @@ static int load_scode(struct dvb_frontend *fe, unsigned int type,
if ((priv->firm[pos].size != 12 * 16) || (scode >= 16)) if ((priv->firm[pos].size != 12 * 16) || (scode >= 16))
return -EINVAL; return -EINVAL;
if (priv->version < 0x0202) { if (priv->version < 0x0202)
send_seq(priv, {0x20, 0x00, 0x00, 0x00}); rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00});
} else { else
send_seq(priv, {0xa0, 0x00, 0x00, 0x00}); rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
} if (rc < 0)
return -EIO;
i2c_send(rc, priv, p + 12 * scode, 12); rc = i2c_send(priv, p + 12 * scode, 12);
if (rc < 0)
return -EIO;
send_seq(priv, {0x00, 0x8c}); rc = send_seq(priv, {0x00, 0x8c});
if (rc < 0)
return -EIO;
return 0; return 0;
} }
...@@ -766,11 +775,12 @@ static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ , ...@@ -766,11 +775,12 @@ static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ ,
/* CMD= Set frequency */ /* CMD= Set frequency */
if (priv->version < 0x0202) { if (priv->version < 0x0202)
send_seq(priv, {0x00, 0x02, 0x00, 0x00}); rc = send_seq(priv, {0x00, 0x02, 0x00, 0x00});
} else { else
send_seq(priv, {0x80, 0x02, 0x00, 0x00}); rc = send_seq(priv, {0x80, 0x02, 0x00, 0x00});
} if (rc < 0)
goto ret;
rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1); rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
if (rc < 0) if (rc < 0)
...@@ -784,7 +794,7 @@ static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ , ...@@ -784,7 +794,7 @@ static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ ,
buf[3] = 0xff & (div); buf[3] = 0xff & (div);
buf[4] = 0; buf[4] = 0;
i2c_send(rc, priv, buf, sizeof(buf)); rc = i2c_send(priv, buf, sizeof(buf));
if (rc < 0) if (rc < 0)
goto ret; goto ret;
msleep(100); msleep(100);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment