Yinghai Lu | 7213d0f | 2004-12-03 03:39:04 +0000 | [diff] [blame] | 1 | #include <console/console.h> |
| 2 | #include <stdint.h> |
| 3 | #include <device/device.h> |
| 4 | #include <device/path.h> |
| 5 | #include <device/smbus.h> |
| 6 | |
| 7 | struct bus *get_pbus_smbus(device_t dev) |
| 8 | { |
| 9 | struct bus *pbus = dev->bus; |
Li-Ta Lo | 9a5b496 | 2004-12-23 21:48:01 +0000 | [diff] [blame] | 10 | while (pbus && pbus->dev && !ops_smbus_bus(pbus)) { |
Yinghai Lu | 7213d0f | 2004-12-03 03:39:04 +0000 | [diff] [blame] | 11 | pbus = pbus->dev->bus; |
| 12 | } |
| 13 | if (!pbus || !pbus->dev || !pbus->dev->ops || !pbus->dev->ops->ops_smbus_bus) { |
| 14 | printk_alert("%s Cannot find smbus bus operations", dev_path(dev)); |
| 15 | die(""); |
| 16 | for(;;); |
| 17 | } |
| 18 | return pbus; |
| 19 | } |
| 20 | |
Li-Ta Lo | 9a5b496 | 2004-12-23 21:48:01 +0000 | [diff] [blame] | 21 | /*multi level i2c MUX??? may need to find the first i2c device and then set link |
| 22 | * down to current dev |
| 23 | 1 store get_pbus_smbus list link |
| 24 | 2 reverse the link and call set link */ |
Yinghai Lu | 7213d0f | 2004-12-03 03:39:04 +0000 | [diff] [blame] | 25 | |
| 26 | int smbus_set_link(device_t dev) |
| 27 | { |
| 28 | struct bus *pbus_a[4]; // 4 level mux only. Enough? |
| 29 | struct bus *pbus = dev->bus; |
| 30 | int pbus_num=0; |
| 31 | int i; |
| 32 | while(pbus && pbus->dev && (pbus->dev->path.type==DEVICE_PATH_I2C)) { |
| 33 | pbus_a[pbus_num++] = pbus; |
| 34 | pbus = pbus->dev->bus; |
| 35 | } |
| 36 | // printk_info("smbus_set_link: "); |
Li-Ta Lo | 9a5b496 | 2004-12-23 21:48:01 +0000 | [diff] [blame] | 37 | for (i=pbus_num-1; i>=0; i--) { |
Yinghai Lu | 7213d0f | 2004-12-03 03:39:04 +0000 | [diff] [blame] | 38 | // printk_info(" %s[%d] -> ", dev_path(pbus_a[i]->dev), pbus_a[i]->link); |
Li-Ta Lo | 9a5b496 | 2004-12-23 21:48:01 +0000 | [diff] [blame] | 39 | if (ops_smbus_bus(get_pbus_smbus(pbus_a[i]->dev))) { |
| 40 | if (pbus_a[i]->dev->ops && pbus_a[i]->dev->ops->set_link) |
Yinghai Lu | 7213d0f | 2004-12-03 03:39:04 +0000 | [diff] [blame] | 41 | pbus_a[i]->dev->ops->set_link(pbus_a[i]->dev, pbus_a[i]->link); |
| 42 | } |
| 43 | } |
| 44 | // printk_info(" %s\n", dev_path(dev)); |
| 45 | |
| 46 | return pbus_num; |
| 47 | } |
| 48 | |
| 49 | int smbus_quick_read(device_t dev) |
| 50 | { |
| 51 | return ops_smbus_bus(get_pbus_smbus(dev))->quick_read(dev); |
| 52 | } |
| 53 | int smbus_quick_write(device_t dev) |
| 54 | { |
| 55 | return ops_smbus_bus(get_pbus_smbus(dev))->quick_write(dev); |
| 56 | } |
| 57 | int smbus_recv_byte(device_t dev) |
| 58 | { |
| 59 | return ops_smbus_bus(get_pbus_smbus(dev))->recv_byte(dev); |
| 60 | } |
| 61 | int smbus_send_byte(device_t dev, uint8_t byte) |
| 62 | { |
| 63 | return ops_smbus_bus(get_pbus_smbus(dev))->send_byte(dev, byte); |
| 64 | } |
| 65 | int smbus_read_byte(device_t dev, uint8_t addr) |
| 66 | { |
| 67 | return ops_smbus_bus(get_pbus_smbus(dev))->read_byte(dev, addr); |
| 68 | } |
| 69 | int smbus_write_byte(device_t dev, uint8_t addr, uint8_t val) |
| 70 | { |
| 71 | return ops_smbus_bus(get_pbus_smbus(dev))->write_byte(dev, addr, val); |
| 72 | } |
| 73 | int smbus_read_word(device_t dev, uint8_t addr) |
| 74 | { |
| 75 | return ops_smbus_bus(get_pbus_smbus(dev))->read_word(dev, addr); |
| 76 | } |
| 77 | int smbus_write_word(device_t dev, uint8_t addr, uint16_t val) |
| 78 | { |
| 79 | return ops_smbus_bus(get_pbus_smbus(dev))->write_word(dev, addr, val); |
| 80 | } |
| 81 | int smbus_process_call(device_t dev, uint8_t cmd, uint16_t data) |
| 82 | { |
| 83 | return ops_smbus_bus(get_pbus_smbus(dev))->process_call(dev, cmd, data); |
| 84 | } |
| 85 | int smbus_block_read(device_t dev, uint8_t cmd, uint8_t bytes, uint8_t *buffer) |
| 86 | { |
| 87 | return ops_smbus_bus(get_pbus_smbus(dev))->block_read(dev, cmd, bytes, buffer); |
| 88 | } |
| 89 | int smbus_block_write(device_t dev, uint8_t cmd, uint8_t bytes, const uint8_t *buffer) |
| 90 | { |
| 91 | return ops_smbus_bus(get_pbus_smbus(dev))->block_write(dev, cmd, bytes, buffer); |
| 92 | } |
| 93 | |
| 94 | |