blob: 8d32a66b8f286ef14db85b3fb170b0ba729bb2c9 [file] [log] [blame]
Yinghai Lu7213d0f2004-12-03 03:39:04 +00001#include <console/console.h>
2#include <stdint.h>
3#include <device/device.h>
4#include <device/path.h>
5#include <device/smbus.h>
6
7struct bus *get_pbus_smbus(device_t dev)
8{
9 struct bus *pbus = dev->bus;
Li-Ta Lo9a5b4962004-12-23 21:48:01 +000010 while (pbus && pbus->dev && !ops_smbus_bus(pbus)) {
Yinghai Lu7213d0f2004-12-03 03:39:04 +000011 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 Lo9a5b4962004-12-23 21:48:01 +000021/*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 Lu7213d0f2004-12-03 03:39:04 +000025
26int 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 Lo9a5b4962004-12-23 21:48:01 +000037 for (i=pbus_num-1; i>=0; i--) {
Yinghai Lu7213d0f2004-12-03 03:39:04 +000038// printk_info(" %s[%d] -> ", dev_path(pbus_a[i]->dev), pbus_a[i]->link);
Li-Ta Lo9a5b4962004-12-23 21:48:01 +000039 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 Lu7213d0f2004-12-03 03:39:04 +000041 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
49int smbus_quick_read(device_t dev)
50{
51 return ops_smbus_bus(get_pbus_smbus(dev))->quick_read(dev);
52}
53int smbus_quick_write(device_t dev)
54{
55 return ops_smbus_bus(get_pbus_smbus(dev))->quick_write(dev);
56}
57int smbus_recv_byte(device_t dev)
58{
59 return ops_smbus_bus(get_pbus_smbus(dev))->recv_byte(dev);
60}
61int smbus_send_byte(device_t dev, uint8_t byte)
62{
63 return ops_smbus_bus(get_pbus_smbus(dev))->send_byte(dev, byte);
64}
65int smbus_read_byte(device_t dev, uint8_t addr)
66{
67 return ops_smbus_bus(get_pbus_smbus(dev))->read_byte(dev, addr);
68}
69int 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}
73int smbus_read_word(device_t dev, uint8_t addr)
74{
75 return ops_smbus_bus(get_pbus_smbus(dev))->read_word(dev, addr);
76}
77int 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}
81int 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}
85int 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}
89int 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