1083a11a3SMarcus Overhagen /*
2083a11a3SMarcus Overhagen * Copyright (c) 2004-2007 Marcus Overhagen <marcus@overhagen.de>
3083a11a3SMarcus Overhagen *
4083a11a3SMarcus Overhagen * Permission is hereby granted, free of charge, to any person
5083a11a3SMarcus Overhagen * obtaining a copy of this software and associated documentation
6083a11a3SMarcus Overhagen * files (the "Software"), to deal in the Software without restriction,
7083a11a3SMarcus Overhagen * including without limitation the rights to use, copy, modify,
8083a11a3SMarcus Overhagen * merge, publish, distribute, sublicense, and/or sell copies of
9083a11a3SMarcus Overhagen * the Software, and to permit persons to whom the Software is
10083a11a3SMarcus Overhagen * furnished to do so, subject to the following conditions:
11083a11a3SMarcus Overhagen *
12083a11a3SMarcus Overhagen * The above copyright notice and this permission notice shall be
13083a11a3SMarcus Overhagen * included in all copies or substantial portions of the Software.
14083a11a3SMarcus Overhagen *
15083a11a3SMarcus Overhagen * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16083a11a3SMarcus Overhagen * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17083a11a3SMarcus Overhagen * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18083a11a3SMarcus Overhagen * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19083a11a3SMarcus Overhagen * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20083a11a3SMarcus Overhagen * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21083a11a3SMarcus Overhagen * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22083a11a3SMarcus Overhagen * OTHER DEALINGS IN THE SOFTWARE.
23083a11a3SMarcus Overhagen */
24083a11a3SMarcus Overhagen
25*1caca357SMarcus Overhagen #include "cx23882_i2c.h"
26*1caca357SMarcus Overhagen #include "i2c_core.h"
27083a11a3SMarcus Overhagen
28083a11a3SMarcus Overhagen
29083a11a3SMarcus Overhagen static void
set_scl(void * cookie,int state)30083a11a3SMarcus Overhagen set_scl(void *cookie, int state)
31083a11a3SMarcus Overhagen {
32083a11a3SMarcus Overhagen cx23882_device * device = cookie;
33083a11a3SMarcus Overhagen if (state)
34083a11a3SMarcus Overhagen device->i2c_reg |= I2C_SCL;
35083a11a3SMarcus Overhagen else
36083a11a3SMarcus Overhagen device->i2c_reg &= ~I2C_SCL;
37083a11a3SMarcus Overhagen reg_write32(REG_I2C_CONTROL, device->i2c_reg);
38083a11a3SMarcus Overhagen reg_read32(REG_I2C_CONTROL); // PCI bridge flush
39083a11a3SMarcus Overhagen }
40083a11a3SMarcus Overhagen
41083a11a3SMarcus Overhagen
42083a11a3SMarcus Overhagen static void
set_sda(void * cookie,int state)43083a11a3SMarcus Overhagen set_sda(void *cookie, int state)
44083a11a3SMarcus Overhagen {
45083a11a3SMarcus Overhagen cx23882_device * device = cookie;
46083a11a3SMarcus Overhagen if (state)
47083a11a3SMarcus Overhagen device->i2c_reg |= I2C_SDA;
48083a11a3SMarcus Overhagen else
49083a11a3SMarcus Overhagen device->i2c_reg &= ~I2C_SDA;
50083a11a3SMarcus Overhagen reg_write32(REG_I2C_CONTROL, device->i2c_reg);
51083a11a3SMarcus Overhagen reg_read32(REG_I2C_CONTROL); // PCI bridge flush
52083a11a3SMarcus Overhagen }
53083a11a3SMarcus Overhagen
54083a11a3SMarcus Overhagen
55083a11a3SMarcus Overhagen static int
get_scl(void * cookie)56083a11a3SMarcus Overhagen get_scl(void *cookie)
57083a11a3SMarcus Overhagen {
58083a11a3SMarcus Overhagen cx23882_device * device = cookie;
59083a11a3SMarcus Overhagen return (reg_read32(REG_I2C_CONTROL) & I2C_SCL) >> 1; // I2C_SCL is 0x02
60083a11a3SMarcus Overhagen }
61083a11a3SMarcus Overhagen
62083a11a3SMarcus Overhagen
63083a11a3SMarcus Overhagen static int
get_sda(void * cookie)64083a11a3SMarcus Overhagen get_sda(void *cookie)
65083a11a3SMarcus Overhagen {
66083a11a3SMarcus Overhagen cx23882_device * device = cookie;
67083a11a3SMarcus Overhagen return reg_read32(REG_I2C_CONTROL) & I2C_SDA; // I2C_SDA is 0x01
68083a11a3SMarcus Overhagen }
69083a11a3SMarcus Overhagen
70083a11a3SMarcus Overhagen
71083a11a3SMarcus Overhagen status_t
i2c_init(cx23882_device * device)72083a11a3SMarcus Overhagen i2c_init(cx23882_device *device)
73083a11a3SMarcus Overhagen {
74083a11a3SMarcus Overhagen device->i2c_bus = i2c_create_bus(device, 80000, 2000000, set_scl, set_sda, get_scl, get_sda);
75083a11a3SMarcus Overhagen device->i2c_reg = reg_read32(REG_I2C_CONTROL);
76083a11a3SMarcus Overhagen device->i2c_reg &= ~I2C_HW_MODE;
77083a11a3SMarcus Overhagen device->i2c_reg |= I2C_SCL | I2C_SDA;
78083a11a3SMarcus Overhagen reg_write32(REG_I2C_CONTROL, device->i2c_reg);
79083a11a3SMarcus Overhagen reg_read32(REG_I2C_CONTROL); // PCI bridge flush
80083a11a3SMarcus Overhagen return device->i2c_bus ? B_OK : B_ERROR;
81083a11a3SMarcus Overhagen }
82083a11a3SMarcus Overhagen
83083a11a3SMarcus Overhagen
84083a11a3SMarcus Overhagen void
i2c_terminate(cx23882_device * device)85083a11a3SMarcus Overhagen i2c_terminate(cx23882_device *device)
86083a11a3SMarcus Overhagen {
87083a11a3SMarcus Overhagen i2c_delete_bus(device->i2c_bus);
88083a11a3SMarcus Overhagen }
89083a11a3SMarcus Overhagen
90083a11a3SMarcus Overhagen
91