2 * This file is part of the coreboot project.
4 * Copyright (C) 2004 Tyan
5 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
6 * Copyright (C) 2004 Li-Ta Lo <ollie@lanl.gov>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <console/console.h>
24 #include <device/device.h>
25 #include <device/path.h>
26 #include <device/smbus.h>
28 struct bus
*get_pbus_smbus(device_t dev
)
30 struct bus
*pbus
= dev
->bus
;
32 while (pbus
&& pbus
->dev
&& !ops_smbus_bus(pbus
))
33 pbus
= pbus
->dev
->bus
;
35 if (!pbus
|| !pbus
->dev
|| !pbus
->dev
->ops
36 || !pbus
->dev
->ops
->ops_smbus_bus
) {
37 printk(BIOS_ALERT
, "%s Cannot find SMBus bus operations",
46 * Multi-level I2C MUX? May need to find the first I2C device and then set link
47 * down to current dev.
49 * 1 store get_pbus_smbus list link
50 * 2 reverse the link and call set link.
54 int smbus_set_link(device_t dev
)
56 struct bus
*pbus_a
[4]; // 4 level mux only. Enough?
57 struct bus
*pbus
= dev
->bus
;
61 while (pbus
&& pbus
->dev
&& (pbus
->dev
->path
.type
== DEVICE_PATH_I2C
)) {
62 pbus_a
[pbus_num
++] = pbus
;
63 pbus
= pbus
->dev
->bus
;
66 // printk(BIOS_INFO, "smbus_set_link: ");
67 for (i
= pbus_num
- 1; i
>= 0; i
--) {
68 // printk(BIOS_INFO, " %s[%d] -> ", dev_path(pbus_a[i]->dev),
70 if (ops_smbus_bus(get_pbus_smbus(pbus_a
[i
]->dev
))) {
71 if (pbus_a
[i
]->dev
->ops
72 && pbus_a
[i
]->dev
->ops
->set_link
)
73 pbus_a
[i
]->dev
->ops
->set_link(pbus_a
[i
]->dev
,
77 // printk(BIOS_INFO, " %s\n", dev_path(dev));
82 int smbus_quick_read(device_t dev
)
84 return ops_smbus_bus(get_pbus_smbus(dev
))->quick_read(dev
);
87 int smbus_quick_write(device_t dev
)
89 return ops_smbus_bus(get_pbus_smbus(dev
))->quick_write(dev
);
92 int smbus_recv_byte(device_t dev
)
94 return ops_smbus_bus(get_pbus_smbus(dev
))->recv_byte(dev
);
97 int smbus_send_byte(device_t dev
, u8 byte
)
99 return ops_smbus_bus(get_pbus_smbus(dev
))->send_byte(dev
, byte
);
102 int smbus_read_byte(device_t dev
, u8 addr
)
104 return ops_smbus_bus(get_pbus_smbus(dev
))->read_byte(dev
, addr
);
107 int smbus_write_byte(device_t dev
, u8 addr
, u8 val
)
109 return ops_smbus_bus(get_pbus_smbus(dev
))->write_byte(dev
, addr
, val
);
112 int smbus_read_word(device_t dev
, u8 addr
)
114 return ops_smbus_bus(get_pbus_smbus(dev
))->read_word(dev
, addr
);
117 int smbus_write_word(device_t dev
, u8 addr
, u16 val
)
119 return ops_smbus_bus(get_pbus_smbus(dev
))->write_word(dev
, addr
, val
);
122 int smbus_process_call(device_t dev
, u8 cmd
, u16 data
)
124 return ops_smbus_bus(get_pbus_smbus(dev
))->process_call(dev
, cmd
, data
);
127 int smbus_block_read(device_t dev
, u8 cmd
, u8 bytes
, u8
*buffer
)
129 return ops_smbus_bus(get_pbus_smbus(dev
))->block_read(dev
, cmd
,
133 int smbus_block_write(device_t dev
, u8 cmd
, u8 bytes
, const u8
*buffer
)
135 return ops_smbus_bus(get_pbus_smbus(dev
))->block_write(dev
, cmd
,