Lines Matching full:smbus

5  * SMBus host driver for PA Semi PWRficient
45 static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val) in reg_write() argument
47 dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val); in reg_write()
48 iowrite32(val, smbus->ioaddr + reg); in reg_write()
51 static inline int reg_read(struct pasemi_smbus *smbus, int reg) in reg_read() argument
54 ret = ioread32(smbus->ioaddr + reg); in reg_read()
55 dev_dbg(smbus->dev, "smbus read reg %x val %08x\n", reg, ret); in reg_read()
59 #define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg)) argument
60 #define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO) argument
62 static void pasemi_reset(struct pasemi_smbus *smbus) in pasemi_reset() argument
64 u32 val = (CTL_MTR | CTL_MRR | (smbus->clk_div & CTL_CLK_M)); in pasemi_reset()
66 if (smbus->hw_rev >= 6) in pasemi_reset()
69 reg_write(smbus, REG_CTL, val); in pasemi_reset()
70 reinit_completion(&smbus->irq_completion); in pasemi_reset()
73 static void pasemi_smb_clear(struct pasemi_smbus *smbus) in pasemi_smb_clear() argument
77 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_clear()
78 reg_write(smbus, REG_SMSTA, status); in pasemi_smb_clear()
81 static int pasemi_smb_waitready(struct pasemi_smbus *smbus) in pasemi_smb_waitready() argument
86 if (smbus->use_irq) { in pasemi_smb_waitready()
87 reinit_completion(&smbus->irq_completion); in pasemi_smb_waitready()
88 reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN); in pasemi_smb_waitready()
89 wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100)); in pasemi_smb_waitready()
90 reg_write(smbus, REG_IMASK, 0); in pasemi_smb_waitready()
91 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
93 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
96 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
105 dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status); in pasemi_smb_waitready()
106 reg_write(smbus, REG_SMSTA, status); in pasemi_smb_waitready()
111 reg_write(smbus, REG_SMSTA, SMSTA_XEN); in pasemi_smb_waitready()
119 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_i2c_xfer_msg() local
125 TXFIFO_WR(smbus, MTXFIFO_START | i2c_8bit_addr_from_msg(msg)); in pasemi_i2c_xfer_msg()
128 TXFIFO_WR(smbus, msg->len | MTXFIFO_READ | in pasemi_i2c_xfer_msg()
131 err = pasemi_smb_waitready(smbus); in pasemi_i2c_xfer_msg()
136 rd = RXFIFO_RD(smbus); in pasemi_i2c_xfer_msg()
145 TXFIFO_WR(smbus, msg->buf[i]); in pasemi_i2c_xfer_msg()
147 TXFIFO_WR(smbus, msg->buf[msg->len-1] | in pasemi_i2c_xfer_msg()
151 err = pasemi_smb_waitready(smbus); in pasemi_i2c_xfer_msg()
160 pasemi_reset(smbus); in pasemi_i2c_xfer_msg()
167 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_i2c_xfer() local
170 pasemi_smb_clear(smbus); in pasemi_i2c_xfer()
184 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_smb_xfer() local
193 pasemi_smb_clear(smbus); in pasemi_smb_xfer()
197 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START | in pasemi_smb_xfer()
201 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START); in pasemi_smb_xfer()
203 TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ); in pasemi_smb_xfer()
205 TXFIFO_WR(smbus, MTXFIFO_STOP | command); in pasemi_smb_xfer()
208 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
209 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
211 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
212 TXFIFO_WR(smbus, 1 | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
214 TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte); in pasemi_smb_xfer()
218 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
219 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
221 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
222 TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
224 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M); in pasemi_smb_xfer()
225 TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8)); in pasemi_smb_xfer()
229 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
230 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
232 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
233 TXFIFO_WR(smbus, 1 | MTXFIFO_READ); in pasemi_smb_xfer()
234 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
237 TXFIFO_WR(smbus, len | MTXFIFO_READ | in pasemi_smb_xfer()
241 TXFIFO_WR(smbus, len); in pasemi_smb_xfer()
243 TXFIFO_WR(smbus, data->block[i]); in pasemi_smb_xfer()
244 TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP); in pasemi_smb_xfer()
249 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
250 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
251 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M); in pasemi_smb_xfer()
252 TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M); in pasemi_smb_xfer()
253 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
254 TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ); in pasemi_smb_xfer()
259 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
260 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
261 TXFIFO_WR(smbus, len); in pasemi_smb_xfer()
263 TXFIFO_WR(smbus, data->block[i]); in pasemi_smb_xfer()
264 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ); in pasemi_smb_xfer()
265 TXFIFO_WR(smbus, MTXFIFO_READ | 1); in pasemi_smb_xfer()
266 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
269 TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
277 err = pasemi_smb_waitready(smbus); in pasemi_smb_xfer()
287 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
296 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
302 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
313 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
326 pasemi_reset(smbus); in pasemi_smb_xfer()
344 int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) in pasemi_i2c_common_probe() argument
348 smbus->adapter.owner = THIS_MODULE; in pasemi_i2c_common_probe()
349 snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), in pasemi_i2c_common_probe()
350 "PA Semi SMBus adapter (%s)", dev_name(smbus->dev)); in pasemi_i2c_common_probe()
351 smbus->adapter.algo = &smbus_algorithm; in pasemi_i2c_common_probe()
352 smbus->adapter.algo_data = smbus; in pasemi_i2c_common_probe()
355 smbus->adapter.dev.parent = smbus->dev; in pasemi_i2c_common_probe()
356 smbus->use_irq = 0; in pasemi_i2c_common_probe()
357 init_completion(&smbus->irq_completion); in pasemi_i2c_common_probe()
359 if (smbus->hw_rev != PASEMI_HW_REV_PCI) in pasemi_i2c_common_probe()
360 smbus->hw_rev = reg_read(smbus, REG_REV); in pasemi_i2c_common_probe()
362 reg_write(smbus, REG_IMASK, 0); in pasemi_i2c_common_probe()
364 pasemi_reset(smbus); in pasemi_i2c_common_probe()
366 error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter); in pasemi_i2c_common_probe()
376 struct pasemi_smbus *smbus = dev_id; in pasemi_irq_handler() local
378 reg_write(smbus, REG_IMASK, 0); in pasemi_irq_handler()
379 complete(&smbus->irq_completion); in pasemi_irq_handler()
386 MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");