0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef __TUNER_I2C_H__
0010 #define __TUNER_I2C_H__
0011
0012 #include <linux/i2c.h>
0013 #include <linux/slab.h>
0014
0015 struct tuner_i2c_props {
0016 u8 addr;
0017 struct i2c_adapter *adap;
0018
0019
0020 int count;
0021 char *name;
0022 };
0023
0024 static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props,
0025 unsigned char *buf, int len)
0026 {
0027 struct i2c_msg msg = { .addr = props->addr, .flags = 0,
0028 .buf = buf, .len = len };
0029 int ret = i2c_transfer(props->adap, &msg, 1);
0030
0031 return (ret == 1) ? len : ret;
0032 }
0033
0034 static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props,
0035 unsigned char *buf, int len)
0036 {
0037 struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
0038 .buf = buf, .len = len };
0039 int ret = i2c_transfer(props->adap, &msg, 1);
0040
0041 return (ret == 1) ? len : ret;
0042 }
0043
0044 static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
0045 unsigned char *obuf, int olen,
0046 unsigned char *ibuf, int ilen)
0047 {
0048 struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
0049 .buf = obuf, .len = olen },
0050 { .addr = props->addr, .flags = I2C_M_RD,
0051 .buf = ibuf, .len = ilen } };
0052 int ret = i2c_transfer(props->adap, msg, 2);
0053
0054 return (ret == 2) ? ilen : ret;
0055 }
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 #define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \
0076 printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \
0077 i2cprops.adap ? \
0078 i2c_adapter_id(i2cprops.adap) : -1, \
0079 i2cprops.addr, ##arg); \
0080 } while (0)
0081
0082
0083
0084
0085 #define __tuner_warn(i2cprops, fmt, arg...) do { \
0086 tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \
0087 } while (0)
0088
0089 #define __tuner_info(i2cprops, fmt, arg...) do { \
0090 tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \
0091 } while (0)
0092
0093 #define __tuner_err(i2cprops, fmt, arg...) do { \
0094 tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \
0095 } while (0)
0096
0097 #define __tuner_dbg(i2cprops, fmt, arg...) do { \
0098 if ((debug)) \
0099 tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \
0100 } while (0)
0101
0102 #define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg)
0103 #define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg)
0104 #define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg)
0105 #define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg)
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119 #define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\
0120 ({ \
0121 int __ret = 0; \
0122 list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \
0123 if (((i2cadap) && (state->i2c_props.adap)) && \
0124 ((i2c_adapter_id(state->i2c_props.adap) == \
0125 i2c_adapter_id(i2cadap)) && \
0126 (i2caddr == state->i2c_props.addr))) { \
0127 __tuner_info(state->i2c_props, \
0128 "attaching existing instance\n"); \
0129 state->i2c_props.count++; \
0130 __ret = state->i2c_props.count; \
0131 break; \
0132 } \
0133 } \
0134 if (0 == __ret) { \
0135 state = kzalloc(sizeof(type), GFP_KERNEL); \
0136 if (!state) { \
0137 __ret = -ENOMEM; \
0138 goto __fail; \
0139 } \
0140 state->i2c_props.addr = i2caddr; \
0141 state->i2c_props.adap = i2cadap; \
0142 state->i2c_props.name = devname; \
0143 __tuner_info(state->i2c_props, \
0144 "creating new instance\n"); \
0145 list_add_tail(&state->hybrid_tuner_instance_list, &list);\
0146 state->i2c_props.count++; \
0147 __ret = state->i2c_props.count; \
0148 } \
0149 __fail: \
0150 __ret; \
0151 })
0152
0153 #define hybrid_tuner_release_state(state) \
0154 ({ \
0155 int __ret; \
0156 state->i2c_props.count--; \
0157 __ret = state->i2c_props.count; \
0158 if (!state->i2c_props.count) { \
0159 __tuner_info(state->i2c_props, "destroying instance\n");\
0160 list_del(&state->hybrid_tuner_instance_list); \
0161 kfree(state); \
0162 } \
0163 __ret; \
0164 })
0165
0166 #define hybrid_tuner_report_instance_count(state) \
0167 ({ \
0168 int __ret = 0; \
0169 if (state) \
0170 __ret = state->i2c_props.count; \
0171 __ret; \
0172 })
0173
0174 #endif