Lines Matching full:smbus
5 * SMBus host driver for PA Semi PWRficient
63 static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val) in reg_write() argument
65 dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val); in reg_write()
66 iowrite32(val, smbus->ioaddr + reg); in reg_write()
69 static inline int reg_read(struct pasemi_smbus *smbus, int reg) in reg_read() argument
72 ret = ioread32(smbus->ioaddr + reg); in reg_read()
73 dev_dbg(smbus->dev, "smbus read reg %x val %08x\n", reg, ret); in reg_read()
77 #define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg)) argument
78 #define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO) argument
80 static void pasemi_reset(struct pasemi_smbus *smbus) in pasemi_reset() argument
82 u32 val = (CTL_MTR | CTL_MRR | CTL_UJM | (smbus->clk_div & CTL_CLK_M)); in pasemi_reset()
84 if (smbus->hw_rev >= 6) in pasemi_reset()
87 reg_write(smbus, REG_CTL, val); in pasemi_reset()
88 reinit_completion(&smbus->irq_completion); in pasemi_reset()
91 static int pasemi_smb_clear(struct pasemi_smbus *smbus) in pasemi_smb_clear() argument
97 ret = readx_poll_timeout(ioread32, smbus->ioaddr + REG_SMSTA, in pasemi_smb_clear()
103 dev_err(smbus->dev, "Bus is still stuck (status 0x%08x xfstatus 0x%08x)\n", in pasemi_smb_clear()
104 status, reg_read(smbus, REG_XFSTA)); in pasemi_smb_clear()
111 dev_warn(smbus->dev, "Issuing reset due to status 0x%08x (xfstatus 0x%08x)\n", in pasemi_smb_clear()
112 status, reg_read(smbus, REG_XFSTA)); in pasemi_smb_clear()
113 pasemi_reset(smbus); in pasemi_smb_clear()
117 reg_write(smbus, REG_SMSTA, status); in pasemi_smb_clear()
122 static int pasemi_smb_waitready(struct pasemi_smbus *smbus) in pasemi_smb_waitready() argument
126 if (smbus->use_irq) { in pasemi_smb_waitready()
127 reinit_completion(&smbus->irq_completion); in pasemi_smb_waitready()
128 reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN); in pasemi_smb_waitready()
130 &smbus->irq_completion, in pasemi_smb_waitready()
132 reg_write(smbus, REG_IMASK, 0); in pasemi_smb_waitready()
133 status = reg_read(smbus, REG_SMSTA); in pasemi_smb_waitready()
136 dev_err(smbus->dev, in pasemi_smb_waitready()
141 dev_err(smbus->dev, "Timeout, status 0x%08x\n", status); in pasemi_smb_waitready()
146 ioread32, smbus->ioaddr + REG_SMSTA, in pasemi_smb_waitready()
152 dev_err(smbus->dev, "Timeout, status 0x%08x\n", status); in pasemi_smb_waitready()
159 dev_err(smbus->dev, "Controller timeout, status 0x%08x\n", status); in pasemi_smb_waitready()
165 dev_err(smbus->dev, "Peripheral timeout, status 0x%08x\n", status); in pasemi_smb_waitready()
171 dev_err(smbus->dev, "Bus stuck, status 0x%08x\n", status); in pasemi_smb_waitready()
177 dev_err(smbus->dev, "Arbitration loss, status 0x%08x\n", status); in pasemi_smb_waitready()
183 dev_err(smbus->dev, "NACK, status 0x%08x\n", status); in pasemi_smb_waitready()
188 reg_write(smbus, REG_SMSTA, SMSTA_XEN); in pasemi_smb_waitready()
196 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_i2c_xfer_msg() local
202 TXFIFO_WR(smbus, MTXFIFO_START | i2c_8bit_addr_from_msg(msg)); in pasemi_i2c_xfer_msg()
205 TXFIFO_WR(smbus, msg->len | MTXFIFO_READ | in pasemi_i2c_xfer_msg()
208 err = pasemi_smb_waitready(smbus); in pasemi_i2c_xfer_msg()
213 rd = RXFIFO_RD(smbus); in pasemi_i2c_xfer_msg()
222 TXFIFO_WR(smbus, msg->buf[i]); in pasemi_i2c_xfer_msg()
224 TXFIFO_WR(smbus, msg->buf[msg->len-1] | in pasemi_i2c_xfer_msg()
228 err = pasemi_smb_waitready(smbus); in pasemi_i2c_xfer_msg()
237 pasemi_reset(smbus); in pasemi_i2c_xfer_msg()
244 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_i2c_xfer() local
247 ret = pasemi_smb_clear(smbus); in pasemi_i2c_xfer()
261 struct pasemi_smbus *smbus = adapter->algo_data; in pasemi_smb_xfer() local
270 err = pasemi_smb_clear(smbus); in pasemi_smb_xfer()
276 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START | in pasemi_smb_xfer()
280 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START); in pasemi_smb_xfer()
282 TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ); in pasemi_smb_xfer()
284 TXFIFO_WR(smbus, MTXFIFO_STOP | command); in pasemi_smb_xfer()
287 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
288 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
290 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
291 TXFIFO_WR(smbus, 1 | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
293 TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte); in pasemi_smb_xfer()
297 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
298 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
300 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
301 TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
303 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M); in pasemi_smb_xfer()
304 TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8)); in pasemi_smb_xfer()
308 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
309 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
311 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
312 TXFIFO_WR(smbus, 1 | MTXFIFO_READ); in pasemi_smb_xfer()
313 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
316 TXFIFO_WR(smbus, len | MTXFIFO_READ | in pasemi_smb_xfer()
320 TXFIFO_WR(smbus, len); in pasemi_smb_xfer()
322 TXFIFO_WR(smbus, data->block[i]); in pasemi_smb_xfer()
323 TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP); in pasemi_smb_xfer()
328 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
329 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
330 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M); in pasemi_smb_xfer()
331 TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M); in pasemi_smb_xfer()
332 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START); in pasemi_smb_xfer()
333 TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ); in pasemi_smb_xfer()
338 TXFIFO_WR(smbus, addr | MTXFIFO_START); in pasemi_smb_xfer()
339 TXFIFO_WR(smbus, command); in pasemi_smb_xfer()
340 TXFIFO_WR(smbus, len); in pasemi_smb_xfer()
342 TXFIFO_WR(smbus, data->block[i]); in pasemi_smb_xfer()
343 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ); in pasemi_smb_xfer()
344 TXFIFO_WR(smbus, MTXFIFO_READ | 1); in pasemi_smb_xfer()
345 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
348 TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP); in pasemi_smb_xfer()
356 err = pasemi_smb_waitready(smbus); in pasemi_smb_xfer()
366 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
375 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
381 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
392 rd = RXFIFO_RD(smbus); in pasemi_smb_xfer()
405 pasemi_reset(smbus); in pasemi_smb_xfer()
423 int pasemi_i2c_common_probe(struct pasemi_smbus *smbus) in pasemi_i2c_common_probe() argument
427 smbus->adapter.owner = THIS_MODULE; in pasemi_i2c_common_probe()
428 snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), in pasemi_i2c_common_probe()
429 "PA Semi SMBus adapter (%s)", dev_name(smbus->dev)); in pasemi_i2c_common_probe()
430 smbus->adapter.algo = &smbus_algorithm; in pasemi_i2c_common_probe()
431 smbus->adapter.algo_data = smbus; in pasemi_i2c_common_probe()
434 smbus->adapter.dev.parent = smbus->dev; in pasemi_i2c_common_probe()
435 smbus->use_irq = 0; in pasemi_i2c_common_probe()
436 init_completion(&smbus->irq_completion); in pasemi_i2c_common_probe()
438 if (smbus->hw_rev != PASEMI_HW_REV_PCI) in pasemi_i2c_common_probe()
439 smbus->hw_rev = reg_read(smbus, REG_REV); in pasemi_i2c_common_probe()
441 reg_write(smbus, REG_IMASK, 0); in pasemi_i2c_common_probe()
443 pasemi_reset(smbus); in pasemi_i2c_common_probe()
445 error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter); in pasemi_i2c_common_probe()
455 struct pasemi_smbus *smbus = dev_id; in pasemi_irq_handler() local
457 reg_write(smbus, REG_IMASK, 0); in pasemi_irq_handler()
458 complete(&smbus->irq_completion); in pasemi_irq_handler()
465 MODULE_DESCRIPTION("PA Semi PWRficient SMBus driver");