Lines Matching full:smbus

5  * SMBus host driver for PA Semi PWRficient
55 static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val) in reg_write() argument
57 dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val); in reg_write()
58 iowrite32(val, smbus->ioaddr + reg); in reg_write()
61 static inline int reg_read(struct pasemi_smbus *smbus, int reg) in reg_read() argument
64 ret = ioread32(smbus->ioaddr + reg); in reg_read()
65 dev_dbg(smbus->dev, "smbus read reg %x val %08x\n", reg, ret); in reg_read()
69 #define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg)) argument
70 #define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO) argument
72 static void pasemi_reset(struct pasemi_smbus *smbus) in pasemi_reset() argument
74 u32 val = (CTL_MTR | CTL_MRR | (smbus->clk_div & CTL_CLK_M)); in pasemi_reset()
76 if (smbus->hw_rev >= 6) in pasemi_reset()
79 reg_write(smbus, REG_CTL, val); in pasemi_reset()
80 reinit_completion(&smbus->irq_completion); in pasemi_reset()
83 static void pasemi_smb_clear(struct pasemi_smbus *smbus) in pasemi_smb_clear() argument
87 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_clear()
88 reg_write(smbus, REG_SMSTA, status); in pasemi_smb_clear()
91 static int pasemi_smb_waitready(struct pasemi_smbus *smbus) in pasemi_smb_waitready() argument
96 if (smbus->use_irq) { in pasemi_smb_waitready()
97 reinit_completion(&smbus->irq_completion); in pasemi_smb_waitready()
98 reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN); in pasemi_smb_waitready()
99 wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100)); in pasemi_smb_waitready()
100 reg_write(smbus, REG_IMASK, 0); in pasemi_smb_waitready()
101 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
103 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
106 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
115 dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status); in pasemi_smb_waitready()
116 reg_write(smbus, REG_SMSTA, status); in pasemi_smb_waitready()
121 reg_write(smbus, REG_SMSTA, SMSTA_XEN); in pasemi_smb_waitready()
129 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_i2c_xfer_msg() local
135 TXFIFO_WR(smbus, MTXFIFO_START | i2c_8bit_addr_from_msg(msg)); in pasemi_i2c_xfer_msg()
138 TXFIFO_WR(smbus, msg->len | MTXFIFO_READ | in pasemi_i2c_xfer_msg()
141 err = pasemi_smb_waitready(smbus); in pasemi_i2c_xfer_msg()
146 rd = RXFIFO_RD(smbus); in pasemi_i2c_xfer_msg()
155 TXFIFO_WR(smbus, msg->buf[i]); in pasemi_i2c_xfer_msg()
157 TXFIFO_WR(smbus, msg->buf[msg->len-1] | in pasemi_i2c_xfer_msg()
161 err = pasemi_smb_waitready(smbus); in pasemi_i2c_xfer_msg()
170 pasemi_reset(smbus); in pasemi_i2c_xfer_msg()
177 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_i2c_xfer() local
180 pasemi_smb_clear(smbus); in pasemi_i2c_xfer()
194 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_smb_xfer() local
203 pasemi_smb_clear(smbus); in pasemi_smb_xfer()
207 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START | in pasemi_smb_xfer()
211 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START); in pasemi_smb_xfer()
213 TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ); in pasemi_smb_xfer()
215 TXFIFO_WR(smbus, MTXFIFO_STOP | command); 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, 1 | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
224 TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte); in pasemi_smb_xfer()
228 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
229 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
231 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
232 TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
234 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M); in pasemi_smb_xfer()
235 TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8)); in pasemi_smb_xfer()
239 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
240 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
242 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
243 TXFIFO_WR(smbus, 1 | MTXFIFO_READ); in pasemi_smb_xfer()
244 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
247 TXFIFO_WR(smbus, len | MTXFIFO_READ | in pasemi_smb_xfer()
251 TXFIFO_WR(smbus, len); in pasemi_smb_xfer()
253 TXFIFO_WR(smbus, data->block[i]); in pasemi_smb_xfer()
254 TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP); 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, data->word & MTXFIFO_DATA_M); in pasemi_smb_xfer()
262 TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M); in pasemi_smb_xfer()
263 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
264 TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ); in pasemi_smb_xfer()
269 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
270 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
271 TXFIFO_WR(smbus, len); in pasemi_smb_xfer()
273 TXFIFO_WR(smbus, data->block[i]); in pasemi_smb_xfer()
274 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ); in pasemi_smb_xfer()
275 TXFIFO_WR(smbus, MTXFIFO_READ | 1); in pasemi_smb_xfer()
276 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
279 TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
287 err = pasemi_smb_waitready(smbus); in pasemi_smb_xfer()
297 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
306 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
312 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
323 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
336 pasemi_reset(smbus); in pasemi_smb_xfer()
354 int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) in pasemi_i2c_common_probe() argument
358 smbus->adapter.owner = THIS_MODULE; in pasemi_i2c_common_probe()
359 snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), in pasemi_i2c_common_probe()
360 "PA Semi SMBus adapter (%s)", dev_name(smbus->dev)); in pasemi_i2c_common_probe()
361 smbus->adapter.algo = &smbus_algorithm; in pasemi_i2c_common_probe()
362 smbus->adapter.algo_data = smbus; in pasemi_i2c_common_probe()
365 smbus->adapter.dev.parent = smbus->dev; in pasemi_i2c_common_probe()
366 smbus->use_irq = 0; in pasemi_i2c_common_probe()
367 init_completion(&smbus->irq_completion); in pasemi_i2c_common_probe()
369 if (smbus->hw_rev != PASEMI_HW_REV_PCI) in pasemi_i2c_common_probe()
370 smbus->hw_rev = reg_read(smbus, REG_REV); in pasemi_i2c_common_probe()
372 reg_write(smbus, REG_IMASK, 0); in pasemi_i2c_common_probe()
374 pasemi_reset(smbus); in pasemi_i2c_common_probe()
376 error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter); in pasemi_i2c_common_probe()
386 struct pasemi_smbus *smbus = dev_id; in pasemi_irq_handler() local
388 reg_write(smbus, REG_IMASK, 0); in pasemi_irq_handler()
389 complete(&smbus->irq_completion); in pasemi_irq_handler()
396 MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");