0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/fb.h>
0009 #include <linux/i2c.h>
0010 #include <linux/io.h>
0011 #include <linux/delay.h>
0012 #include <linux/export.h>
0013
0014 #include "mb862xxfb.h"
0015 #include "mb862xx_reg.h"
0016
0017 static int mb862xx_i2c_wait_event(struct i2c_adapter *adap)
0018 {
0019 struct mb862xxfb_par *par = adap->algo_data;
0020 u32 reg;
0021
0022 do {
0023 udelay(10);
0024 reg = inreg(i2c, GC_I2C_BCR);
0025 if (reg & (I2C_INT | I2C_BER))
0026 break;
0027 } while (1);
0028
0029 return (reg & I2C_BER) ? 0 : 1;
0030 }
0031
0032 static int mb862xx_i2c_do_address(struct i2c_adapter *adap, int addr)
0033 {
0034 struct mb862xxfb_par *par = adap->algo_data;
0035
0036 outreg(i2c, GC_I2C_DAR, addr);
0037 outreg(i2c, GC_I2C_CCR, I2C_CLOCK_AND_ENABLE);
0038 outreg(i2c, GC_I2C_BCR, par->i2c_rs ? I2C_REPEATED_START : I2C_START);
0039 if (!mb862xx_i2c_wait_event(adap))
0040 return -EIO;
0041 par->i2c_rs = !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
0042 return par->i2c_rs;
0043 }
0044
0045 static int mb862xx_i2c_write_byte(struct i2c_adapter *adap, u8 byte)
0046 {
0047 struct mb862xxfb_par *par = adap->algo_data;
0048
0049 outreg(i2c, GC_I2C_DAR, byte);
0050 outreg(i2c, GC_I2C_BCR, I2C_START);
0051 if (!mb862xx_i2c_wait_event(adap))
0052 return -EIO;
0053 return !(inreg(i2c, GC_I2C_BSR) & I2C_LRB);
0054 }
0055
0056 static int mb862xx_i2c_read_byte(struct i2c_adapter *adap, u8 *byte, int last)
0057 {
0058 struct mb862xxfb_par *par = adap->algo_data;
0059
0060 outreg(i2c, GC_I2C_BCR, I2C_START | (last ? 0 : I2C_ACK));
0061 if (!mb862xx_i2c_wait_event(adap))
0062 return 0;
0063 *byte = inreg(i2c, GC_I2C_DAR);
0064 return 1;
0065 }
0066
0067 static void mb862xx_i2c_stop(struct i2c_adapter *adap)
0068 {
0069 struct mb862xxfb_par *par = adap->algo_data;
0070
0071 outreg(i2c, GC_I2C_BCR, I2C_STOP);
0072 outreg(i2c, GC_I2C_CCR, I2C_DISABLE);
0073 par->i2c_rs = 0;
0074 }
0075
0076 static int mb862xx_i2c_read(struct i2c_adapter *adap, struct i2c_msg *m)
0077 {
0078 int i, ret = 0;
0079 int last = m->len - 1;
0080
0081 for (i = 0; i < m->len; i++) {
0082 if (!mb862xx_i2c_read_byte(adap, &m->buf[i], i == last)) {
0083 ret = -EIO;
0084 break;
0085 }
0086 }
0087 return ret;
0088 }
0089
0090 static int mb862xx_i2c_write(struct i2c_adapter *adap, struct i2c_msg *m)
0091 {
0092 int i, ret = 0;
0093
0094 for (i = 0; i < m->len; i++) {
0095 if (!mb862xx_i2c_write_byte(adap, m->buf[i])) {
0096 ret = -EIO;
0097 break;
0098 }
0099 }
0100 return ret;
0101 }
0102
0103 static int mb862xx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
0104 int num)
0105 {
0106 struct mb862xxfb_par *par = adap->algo_data;
0107 struct i2c_msg *m;
0108 int addr;
0109 int i = 0, err = 0;
0110
0111 dev_dbg(par->dev, "%s: %d msgs\n", __func__, num);
0112
0113 for (i = 0; i < num; i++) {
0114 m = &msgs[i];
0115 if (!m->len) {
0116 dev_dbg(par->dev, "%s: null msgs\n", __func__);
0117 continue;
0118 }
0119 addr = m->addr;
0120 if (m->flags & I2C_M_RD)
0121 addr |= 1;
0122
0123 err = mb862xx_i2c_do_address(adap, addr);
0124 if (err < 0)
0125 break;
0126 if (m->flags & I2C_M_RD)
0127 err = mb862xx_i2c_read(adap, m);
0128 else
0129 err = mb862xx_i2c_write(adap, m);
0130 }
0131
0132 if (i)
0133 mb862xx_i2c_stop(adap);
0134
0135 return (err < 0) ? err : i;
0136 }
0137
0138 static u32 mb862xx_func(struct i2c_adapter *adap)
0139 {
0140 return I2C_FUNC_SMBUS_BYTE_DATA;
0141 }
0142
0143 static const struct i2c_algorithm mb862xx_algo = {
0144 .master_xfer = mb862xx_xfer,
0145 .functionality = mb862xx_func,
0146 };
0147
0148 static struct i2c_adapter mb862xx_i2c_adapter = {
0149 .name = "MB862xx I2C adapter",
0150 .algo = &mb862xx_algo,
0151 .owner = THIS_MODULE,
0152 };
0153
0154 int mb862xx_i2c_init(struct mb862xxfb_par *par)
0155 {
0156 mb862xx_i2c_adapter.algo_data = par;
0157 par->adap = &mb862xx_i2c_adapter;
0158
0159 return i2c_add_adapter(par->adap);
0160 }
0161
0162 void mb862xx_i2c_exit(struct mb862xxfb_par *par)
0163 {
0164 if (par->adap) {
0165 i2c_del_adapter(par->adap);
0166 par->adap = NULL;
0167 }
0168 }