1a28d3af2SBenjamin Herrenschmidt /* 2a28d3af2SBenjamin Herrenschmidt i2c Support for Apple SMU Controller 3a28d3af2SBenjamin Herrenschmidt 4a28d3af2SBenjamin Herrenschmidt Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp. 5a28d3af2SBenjamin Herrenschmidt <benh@kernel.crashing.org> 6a28d3af2SBenjamin Herrenschmidt 7a28d3af2SBenjamin Herrenschmidt This program is free software; you can redistribute it and/or modify 8a28d3af2SBenjamin Herrenschmidt it under the terms of the GNU General Public License as published by 9a28d3af2SBenjamin Herrenschmidt the Free Software Foundation; either version 2 of the License, or 10a28d3af2SBenjamin Herrenschmidt (at your option) any later version. 11a28d3af2SBenjamin Herrenschmidt 12a28d3af2SBenjamin Herrenschmidt This program is distributed in the hope that it will be useful, 13a28d3af2SBenjamin Herrenschmidt but WITHOUT ANY WARRANTY; without even the implied warranty of 14a28d3af2SBenjamin Herrenschmidt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15a28d3af2SBenjamin Herrenschmidt GNU General Public License for more details. 16a28d3af2SBenjamin Herrenschmidt 17a28d3af2SBenjamin Herrenschmidt */ 18a28d3af2SBenjamin Herrenschmidt 19a28d3af2SBenjamin Herrenschmidt #include <linux/module.h> 20a28d3af2SBenjamin Herrenschmidt #include <linux/kernel.h> 21a28d3af2SBenjamin Herrenschmidt #include <linux/types.h> 22a28d3af2SBenjamin Herrenschmidt #include <linux/i2c.h> 23a28d3af2SBenjamin Herrenschmidt #include <linux/device.h> 24a28d3af2SBenjamin Herrenschmidt #include <linux/platform_device.h> 255af50730SRob Herring #include <linux/of_irq.h> 26a28d3af2SBenjamin Herrenschmidt #include <asm/prom.h> 27a28d3af2SBenjamin Herrenschmidt #include <asm/pmac_low_i2c.h> 28a28d3af2SBenjamin Herrenschmidt 29a28d3af2SBenjamin Herrenschmidt MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); 30a28d3af2SBenjamin Herrenschmidt MODULE_DESCRIPTION("I2C driver for Apple PowerMac"); 31a28d3af2SBenjamin Herrenschmidt MODULE_LICENSE("GPL"); 32a28d3af2SBenjamin Herrenschmidt 33a28d3af2SBenjamin Herrenschmidt /* 34a28d3af2SBenjamin Herrenschmidt * SMBUS-type transfer entrypoint 35a28d3af2SBenjamin Herrenschmidt */ 36a28d3af2SBenjamin Herrenschmidt static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap, 37a28d3af2SBenjamin Herrenschmidt u16 addr, 38a28d3af2SBenjamin Herrenschmidt unsigned short flags, 39a28d3af2SBenjamin Herrenschmidt char read_write, 40a28d3af2SBenjamin Herrenschmidt u8 command, 41a28d3af2SBenjamin Herrenschmidt int size, 42a28d3af2SBenjamin Herrenschmidt union i2c_smbus_data* data) 43a28d3af2SBenjamin Herrenschmidt { 44a28d3af2SBenjamin Herrenschmidt struct pmac_i2c_bus *bus = i2c_get_adapdata(adap); 45a28d3af2SBenjamin Herrenschmidt int rc = 0; 46a28d3af2SBenjamin Herrenschmidt int read = (read_write == I2C_SMBUS_READ); 47a28d3af2SBenjamin Herrenschmidt int addrdir = (addr << 1) | read; 4802864d58SJean Delvare int mode, subsize, len; 4902864d58SJean Delvare u32 subaddr; 5002864d58SJean Delvare u8 *buf; 51a28d3af2SBenjamin Herrenschmidt u8 local[2]; 52a28d3af2SBenjamin Herrenschmidt 5302864d58SJean Delvare if (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE) { 5402864d58SJean Delvare mode = pmac_i2c_mode_std; 5502864d58SJean Delvare subsize = 0; 5602864d58SJean Delvare subaddr = 0; 5702864d58SJean Delvare } else { 5802864d58SJean Delvare mode = read ? pmac_i2c_mode_combined : pmac_i2c_mode_stdsub; 5902864d58SJean Delvare subsize = 1; 6002864d58SJean Delvare subaddr = command; 6102864d58SJean Delvare } 62a28d3af2SBenjamin Herrenschmidt 63a28d3af2SBenjamin Herrenschmidt switch (size) { 64a28d3af2SBenjamin Herrenschmidt case I2C_SMBUS_QUICK: 6502864d58SJean Delvare buf = NULL; 6602864d58SJean Delvare len = 0; 67a28d3af2SBenjamin Herrenschmidt break; 68a28d3af2SBenjamin Herrenschmidt case I2C_SMBUS_BYTE: 69a28d3af2SBenjamin Herrenschmidt case I2C_SMBUS_BYTE_DATA: 7002864d58SJean Delvare buf = &data->byte; 7102864d58SJean Delvare len = 1; 72a28d3af2SBenjamin Herrenschmidt break; 73a28d3af2SBenjamin Herrenschmidt case I2C_SMBUS_WORD_DATA: 74a28d3af2SBenjamin Herrenschmidt if (!read) { 75a28d3af2SBenjamin Herrenschmidt local[0] = data->word & 0xff; 76a28d3af2SBenjamin Herrenschmidt local[1] = (data->word >> 8) & 0xff; 77a28d3af2SBenjamin Herrenschmidt } 7802864d58SJean Delvare buf = local; 7902864d58SJean Delvare len = 2; 80a28d3af2SBenjamin Herrenschmidt break; 81a28d3af2SBenjamin Herrenschmidt 82a28d3af2SBenjamin Herrenschmidt /* Note that these are broken vs. the expected smbus API where 8396acafe0SJoe Perches * on reads, the length is actually returned from the function, 84a28d3af2SBenjamin Herrenschmidt * but I think the current API makes no sense and I don't want 85a28d3af2SBenjamin Herrenschmidt * any driver that I haven't verified for correctness to go 86a28d3af2SBenjamin Herrenschmidt * anywhere near a pmac i2c bus anyway ... 87a28d3af2SBenjamin Herrenschmidt * 88a28d3af2SBenjamin Herrenschmidt * I'm also not completely sure what kind of phases to do between 89a28d3af2SBenjamin Herrenschmidt * the actual command and the data (what I am _supposed_ to do that 90a28d3af2SBenjamin Herrenschmidt * is). For now, I assume writes are a single stream and reads have 91a28d3af2SBenjamin Herrenschmidt * a repeat start/addr phase (but not stop in between) 92a28d3af2SBenjamin Herrenschmidt */ 93a28d3af2SBenjamin Herrenschmidt case I2C_SMBUS_BLOCK_DATA: 9402864d58SJean Delvare buf = data->block; 9502864d58SJean Delvare len = data->block[0] + 1; 96a28d3af2SBenjamin Herrenschmidt break; 97a28d3af2SBenjamin Herrenschmidt case I2C_SMBUS_I2C_BLOCK_DATA: 9802864d58SJean Delvare buf = &data->block[1]; 9902864d58SJean Delvare len = data->block[0]; 100a28d3af2SBenjamin Herrenschmidt break; 101a28d3af2SBenjamin Herrenschmidt 102a28d3af2SBenjamin Herrenschmidt default: 10302864d58SJean Delvare return -EINVAL; 104a28d3af2SBenjamin Herrenschmidt } 10502864d58SJean Delvare 10602864d58SJean Delvare rc = pmac_i2c_open(bus, 0); 107d7d838a6SJean Delvare if (rc) { 108d7d838a6SJean Delvare dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc); 10902864d58SJean Delvare return rc; 110d7d838a6SJean Delvare } 11102864d58SJean Delvare 11202864d58SJean Delvare rc = pmac_i2c_setmode(bus, mode); 113d7d838a6SJean Delvare if (rc) { 114d7d838a6SJean Delvare dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n", 115d7d838a6SJean Delvare mode, rc); 11602864d58SJean Delvare goto bail; 117d7d838a6SJean Delvare } 11802864d58SJean Delvare 11902864d58SJean Delvare rc = pmac_i2c_xfer(bus, addrdir, subsize, subaddr, buf, len); 120d7d838a6SJean Delvare if (rc) { 1218e4b980cSJean Delvare if (rc == -ENXIO) 1228e4b980cSJean Delvare dev_dbg(&adap->dev, 1238e4b980cSJean Delvare "I2C transfer at 0x%02x failed, size %d, " 1248e4b980cSJean Delvare "err %d\n", addrdir >> 1, size, rc); 1258e4b980cSJean Delvare else 126d7d838a6SJean Delvare dev_err(&adap->dev, 1278e4b980cSJean Delvare "I2C transfer at 0x%02x failed, size %d, " 1288e4b980cSJean Delvare "err %d\n", addrdir >> 1, size, rc); 12902864d58SJean Delvare goto bail; 130d7d838a6SJean Delvare } 13102864d58SJean Delvare 13202864d58SJean Delvare if (size == I2C_SMBUS_WORD_DATA && read) { 13302864d58SJean Delvare data->word = ((u16)local[1]) << 8; 13402864d58SJean Delvare data->word |= local[0]; 13502864d58SJean Delvare } 13602864d58SJean Delvare 137a28d3af2SBenjamin Herrenschmidt bail: 138a28d3af2SBenjamin Herrenschmidt pmac_i2c_close(bus); 139a28d3af2SBenjamin Herrenschmidt return rc; 140a28d3af2SBenjamin Herrenschmidt } 141a28d3af2SBenjamin Herrenschmidt 142a28d3af2SBenjamin Herrenschmidt /* 143a28d3af2SBenjamin Herrenschmidt * Generic i2c master transfer entrypoint. This driver only support single 144a28d3af2SBenjamin Herrenschmidt * messages (for "lame i2c" transfers). Anything else should use the smbus 145a28d3af2SBenjamin Herrenschmidt * entry point 146a28d3af2SBenjamin Herrenschmidt */ 147a28d3af2SBenjamin Herrenschmidt static int i2c_powermac_master_xfer( struct i2c_adapter *adap, 148a28d3af2SBenjamin Herrenschmidt struct i2c_msg *msgs, 149a28d3af2SBenjamin Herrenschmidt int num) 150a28d3af2SBenjamin Herrenschmidt { 151a28d3af2SBenjamin Herrenschmidt struct pmac_i2c_bus *bus = i2c_get_adapdata(adap); 152a28d3af2SBenjamin Herrenschmidt int rc = 0; 153a28d3af2SBenjamin Herrenschmidt int addrdir; 154a28d3af2SBenjamin Herrenschmidt 155a28d3af2SBenjamin Herrenschmidt if (msgs->flags & I2C_M_TEN) 156a28d3af2SBenjamin Herrenschmidt return -EINVAL; 1577756e1eeSWolfram Sang addrdir = i2c_8bit_addr_from_msg(msgs); 158a28d3af2SBenjamin Herrenschmidt 159a28d3af2SBenjamin Herrenschmidt rc = pmac_i2c_open(bus, 0); 160d7d838a6SJean Delvare if (rc) { 161d7d838a6SJean Delvare dev_err(&adap->dev, "Failed to open I2C, err %d\n", rc); 162a28d3af2SBenjamin Herrenschmidt return rc; 163d7d838a6SJean Delvare } 164a28d3af2SBenjamin Herrenschmidt rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); 165d7d838a6SJean Delvare if (rc) { 166d7d838a6SJean Delvare dev_err(&adap->dev, "Failed to set I2C mode %d, err %d\n", 167d7d838a6SJean Delvare pmac_i2c_mode_std, rc); 168a28d3af2SBenjamin Herrenschmidt goto bail; 169d7d838a6SJean Delvare } 170a28d3af2SBenjamin Herrenschmidt rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); 1718e4b980cSJean Delvare if (rc < 0) { 1728e4b980cSJean Delvare if (rc == -ENXIO) 1738e4b980cSJean Delvare dev_dbg(&adap->dev, "I2C %s 0x%02x failed, err %d\n", 1748e4b980cSJean Delvare addrdir & 1 ? "read from" : "write to", 1758e4b980cSJean Delvare addrdir >> 1, rc); 1768e4b980cSJean Delvare else 177d7d838a6SJean Delvare dev_err(&adap->dev, "I2C %s 0x%02x failed, err %d\n", 1788e4b980cSJean Delvare addrdir & 1 ? "read from" : "write to", 1798e4b980cSJean Delvare addrdir >> 1, rc); 1808e4b980cSJean Delvare } 181a28d3af2SBenjamin Herrenschmidt bail: 182a28d3af2SBenjamin Herrenschmidt pmac_i2c_close(bus); 1838ced8eeeSJean Delvare return rc < 0 ? rc : 1; 184a28d3af2SBenjamin Herrenschmidt } 185a28d3af2SBenjamin Herrenschmidt 186a28d3af2SBenjamin Herrenschmidt static u32 i2c_powermac_func(struct i2c_adapter * adapter) 187a28d3af2SBenjamin Herrenschmidt { 188a28d3af2SBenjamin Herrenschmidt return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | 189a28d3af2SBenjamin Herrenschmidt I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | 190a28d3af2SBenjamin Herrenschmidt I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C; 191a28d3af2SBenjamin Herrenschmidt } 192a28d3af2SBenjamin Herrenschmidt 193a28d3af2SBenjamin Herrenschmidt /* For now, we only handle smbus */ 1948f9082c5SJean Delvare static const struct i2c_algorithm i2c_powermac_algorithm = { 195a28d3af2SBenjamin Herrenschmidt .smbus_xfer = i2c_powermac_smbus_xfer, 196a28d3af2SBenjamin Herrenschmidt .master_xfer = i2c_powermac_master_xfer, 197a28d3af2SBenjamin Herrenschmidt .functionality = i2c_powermac_func, 198a28d3af2SBenjamin Herrenschmidt }; 199a28d3af2SBenjamin Herrenschmidt 2007ee405eaSWolfram Sang static struct i2c_adapter_quirks i2c_powermac_quirks = { 2017ee405eaSWolfram Sang .max_num_msgs = 1, 2027ee405eaSWolfram Sang }; 203a28d3af2SBenjamin Herrenschmidt 2040b255e92SBill Pemberton static int i2c_powermac_remove(struct platform_device *dev) 205a28d3af2SBenjamin Herrenschmidt { 2069f2545c1SBenjamin Herrenschmidt struct i2c_adapter *adapter = platform_get_drvdata(dev); 207a28d3af2SBenjamin Herrenschmidt 208bf51a8c5SLars-Peter Clausen i2c_del_adapter(adapter); 2096dfa5ca3SJean Delvare memset(adapter, 0, sizeof(*adapter)); 210a28d3af2SBenjamin Herrenschmidt 211a28d3af2SBenjamin Herrenschmidt return 0; 212a28d3af2SBenjamin Herrenschmidt } 213a28d3af2SBenjamin Herrenschmidt 2140b255e92SBill Pemberton static u32 i2c_powermac_get_addr(struct i2c_adapter *adap, 2153a3dd018SBenjamin Herrenschmidt struct pmac_i2c_bus *bus, 2163a3dd018SBenjamin Herrenschmidt struct device_node *node) 21781e5d864SBenjamin Herrenschmidt { 2183a3dd018SBenjamin Herrenschmidt const __be32 *prop; 21981e5d864SBenjamin Herrenschmidt int len; 22081e5d864SBenjamin Herrenschmidt 2213a3dd018SBenjamin Herrenschmidt /* First check for valid "reg" */ 2223a3dd018SBenjamin Herrenschmidt prop = of_get_property(node, "reg", &len); 2233a3dd018SBenjamin Herrenschmidt if (prop && (len >= sizeof(int))) 2243a3dd018SBenjamin Herrenschmidt return (be32_to_cpup(prop) & 0xff) >> 1; 2253a3dd018SBenjamin Herrenschmidt 2263a3dd018SBenjamin Herrenschmidt /* Then check old-style "i2c-address" */ 2273a3dd018SBenjamin Herrenschmidt prop = of_get_property(node, "i2c-address", &len); 2283a3dd018SBenjamin Herrenschmidt if (prop && (len >= sizeof(int))) 2293a3dd018SBenjamin Herrenschmidt return (be32_to_cpup(prop) & 0xff) >> 1; 2303a3dd018SBenjamin Herrenschmidt 2313a3dd018SBenjamin Herrenschmidt /* Now handle some devices with missing "reg" properties */ 2323a3dd018SBenjamin Herrenschmidt if (!strcmp(node->name, "cereal")) 2333a3dd018SBenjamin Herrenschmidt return 0x60; 2343a3dd018SBenjamin Herrenschmidt else if (!strcmp(node->name, "deq")) 2353a3dd018SBenjamin Herrenschmidt return 0x34; 2363a3dd018SBenjamin Herrenschmidt 237*453a237cSRob Herring dev_warn(&adap->dev, "No i2c address for %pOF\n", node); 2383a3dd018SBenjamin Herrenschmidt 2393a3dd018SBenjamin Herrenschmidt return 0xffffffff; 24081e5d864SBenjamin Herrenschmidt } 24181e5d864SBenjamin Herrenschmidt 2420b255e92SBill Pemberton static void i2c_powermac_create_one(struct i2c_adapter *adap, 2433a3dd018SBenjamin Herrenschmidt const char *type, 2443a3dd018SBenjamin Herrenschmidt u32 addr) 2453a3dd018SBenjamin Herrenschmidt { 2463a3dd018SBenjamin Herrenschmidt struct i2c_board_info info = {}; 2473a3dd018SBenjamin Herrenschmidt struct i2c_client *newdev; 24881e5d864SBenjamin Herrenschmidt 2493a3dd018SBenjamin Herrenschmidt strncpy(info.type, type, sizeof(info.type)); 2503a3dd018SBenjamin Herrenschmidt info.addr = addr; 2513a3dd018SBenjamin Herrenschmidt newdev = i2c_new_device(adap, &info); 2523a3dd018SBenjamin Herrenschmidt if (!newdev) 2533a3dd018SBenjamin Herrenschmidt dev_err(&adap->dev, 2543a3dd018SBenjamin Herrenschmidt "i2c-powermac: Failure to register missing %s\n", 2553a3dd018SBenjamin Herrenschmidt type); 2563a3dd018SBenjamin Herrenschmidt } 25781e5d864SBenjamin Herrenschmidt 2580b255e92SBill Pemberton static void i2c_powermac_add_missing(struct i2c_adapter *adap, 2593a3dd018SBenjamin Herrenschmidt struct pmac_i2c_bus *bus, 2603a3dd018SBenjamin Herrenschmidt bool found_onyx) 2613a3dd018SBenjamin Herrenschmidt { 2623a3dd018SBenjamin Herrenschmidt struct device_node *busnode = pmac_i2c_get_bus_node(bus); 2633a3dd018SBenjamin Herrenschmidt int rc; 2643a3dd018SBenjamin Herrenschmidt 2653a3dd018SBenjamin Herrenschmidt /* Check for the onyx audio codec */ 2663a3dd018SBenjamin Herrenschmidt #define ONYX_REG_CONTROL 67 2673a3dd018SBenjamin Herrenschmidt if (of_device_is_compatible(busnode, "k2-i2c") && !found_onyx) { 2683a3dd018SBenjamin Herrenschmidt union i2c_smbus_data data; 2693a3dd018SBenjamin Herrenschmidt 2703a3dd018SBenjamin Herrenschmidt rc = i2c_smbus_xfer(adap, 0x46, 0, I2C_SMBUS_READ, 2713a3dd018SBenjamin Herrenschmidt ONYX_REG_CONTROL, I2C_SMBUS_BYTE_DATA, 2723a3dd018SBenjamin Herrenschmidt &data); 2733a3dd018SBenjamin Herrenschmidt if (rc >= 0) 2743a3dd018SBenjamin Herrenschmidt i2c_powermac_create_one(adap, "MAC,pcm3052", 0x46); 2753a3dd018SBenjamin Herrenschmidt 2763a3dd018SBenjamin Herrenschmidt rc = i2c_smbus_xfer(adap, 0x47, 0, I2C_SMBUS_READ, 2773a3dd018SBenjamin Herrenschmidt ONYX_REG_CONTROL, I2C_SMBUS_BYTE_DATA, 2783a3dd018SBenjamin Herrenschmidt &data); 2793a3dd018SBenjamin Herrenschmidt if (rc >= 0) 2803a3dd018SBenjamin Herrenschmidt i2c_powermac_create_one(adap, "MAC,pcm3052", 0x47); 2813a3dd018SBenjamin Herrenschmidt } 2823a3dd018SBenjamin Herrenschmidt } 2833a3dd018SBenjamin Herrenschmidt 2840b255e92SBill Pemberton static bool i2c_powermac_get_type(struct i2c_adapter *adap, 2853a3dd018SBenjamin Herrenschmidt struct device_node *node, 2863a3dd018SBenjamin Herrenschmidt u32 addr, char *type, int type_size) 2873a3dd018SBenjamin Herrenschmidt { 2883a3dd018SBenjamin Herrenschmidt char tmp[16]; 2893a3dd018SBenjamin Herrenschmidt 2903a3dd018SBenjamin Herrenschmidt /* Note: we to _NOT_ want the standard 29181e5d864SBenjamin Herrenschmidt * i2c drivers to match with any of our powermac stuff 29281e5d864SBenjamin Herrenschmidt * unless they have been specifically modified to handle 29381e5d864SBenjamin Herrenschmidt * it on a case by case basis. For example, for thermal 29481e5d864SBenjamin Herrenschmidt * control, things like lm75 etc... shall match with their 29581e5d864SBenjamin Herrenschmidt * corresponding windfarm drivers, _NOT_ the generic ones, 29681e5d864SBenjamin Herrenschmidt * so we force a prefix of AAPL, onto the modalias to 29781e5d864SBenjamin Herrenschmidt * make that happen 29881e5d864SBenjamin Herrenschmidt */ 2993a3dd018SBenjamin Herrenschmidt 3003a3dd018SBenjamin Herrenschmidt /* First try proper modalias */ 3013a3dd018SBenjamin Herrenschmidt if (of_modalias_node(node, tmp, sizeof(tmp)) >= 0) { 3023a3dd018SBenjamin Herrenschmidt snprintf(type, type_size, "MAC,%s", tmp); 3033a3dd018SBenjamin Herrenschmidt return true; 3043a3dd018SBenjamin Herrenschmidt } 3053a3dd018SBenjamin Herrenschmidt 3063a3dd018SBenjamin Herrenschmidt /* Now look for known workarounds */ 3073a3dd018SBenjamin Herrenschmidt if (!strcmp(node->name, "deq")) { 3083a3dd018SBenjamin Herrenschmidt /* Apple uses address 0x34 for TAS3001 and 0x35 for TAS3004 */ 3093a3dd018SBenjamin Herrenschmidt if (addr == 0x34) { 3103a3dd018SBenjamin Herrenschmidt snprintf(type, type_size, "MAC,tas3001"); 3113a3dd018SBenjamin Herrenschmidt return true; 3123a3dd018SBenjamin Herrenschmidt } else if (addr == 0x35) { 3133a3dd018SBenjamin Herrenschmidt snprintf(type, type_size, "MAC,tas3004"); 3143a3dd018SBenjamin Herrenschmidt return true; 3153a3dd018SBenjamin Herrenschmidt } 3163a3dd018SBenjamin Herrenschmidt } 3173a3dd018SBenjamin Herrenschmidt 318*453a237cSRob Herring dev_err(&adap->dev, "i2c-powermac: modalias failure on %pOF\n", node); 3193a3dd018SBenjamin Herrenschmidt return false; 3203a3dd018SBenjamin Herrenschmidt } 3213a3dd018SBenjamin Herrenschmidt 3220b255e92SBill Pemberton static void i2c_powermac_register_devices(struct i2c_adapter *adap, 3233a3dd018SBenjamin Herrenschmidt struct pmac_i2c_bus *bus) 3243a3dd018SBenjamin Herrenschmidt { 3253a3dd018SBenjamin Herrenschmidt struct i2c_client *newdev; 3263a3dd018SBenjamin Herrenschmidt struct device_node *node; 3273a3dd018SBenjamin Herrenschmidt bool found_onyx = 0; 3283a3dd018SBenjamin Herrenschmidt 3293a3dd018SBenjamin Herrenschmidt /* 3303a3dd018SBenjamin Herrenschmidt * In some cases we end up with the via-pmu node itself, in this 3313a3dd018SBenjamin Herrenschmidt * case we skip this function completely as the device-tree will 3323a3dd018SBenjamin Herrenschmidt * not contain anything useful. 3333a3dd018SBenjamin Herrenschmidt */ 3343a3dd018SBenjamin Herrenschmidt if (!strcmp(adap->dev.of_node->name, "via-pmu")) 3353a3dd018SBenjamin Herrenschmidt return; 3363a3dd018SBenjamin Herrenschmidt 3373a3dd018SBenjamin Herrenschmidt for_each_child_of_node(adap->dev.of_node, node) { 3383a3dd018SBenjamin Herrenschmidt struct i2c_board_info info = {}; 3393a3dd018SBenjamin Herrenschmidt u32 addr; 3403a3dd018SBenjamin Herrenschmidt 3413a3dd018SBenjamin Herrenschmidt /* Get address & channel */ 3423a3dd018SBenjamin Herrenschmidt addr = i2c_powermac_get_addr(adap, bus, node); 3433a3dd018SBenjamin Herrenschmidt if (addr == 0xffffffff) 3443a3dd018SBenjamin Herrenschmidt continue; 3453a3dd018SBenjamin Herrenschmidt 3463a3dd018SBenjamin Herrenschmidt /* Multibus setup, check channel */ 3473a3dd018SBenjamin Herrenschmidt if (!pmac_i2c_match_adapter(node, adap)) 3483a3dd018SBenjamin Herrenschmidt continue; 3493a3dd018SBenjamin Herrenschmidt 350*453a237cSRob Herring dev_dbg(&adap->dev, "i2c-powermac: register %pOF\n", node); 3513a3dd018SBenjamin Herrenschmidt 3523a3dd018SBenjamin Herrenschmidt /* 3533a3dd018SBenjamin Herrenschmidt * Keep track of some device existence to handle 3543a3dd018SBenjamin Herrenschmidt * workarounds later. 3553a3dd018SBenjamin Herrenschmidt */ 3563a3dd018SBenjamin Herrenschmidt if (of_device_is_compatible(node, "pcm3052")) 3573a3dd018SBenjamin Herrenschmidt found_onyx = true; 3583a3dd018SBenjamin Herrenschmidt 3593a3dd018SBenjamin Herrenschmidt /* Make up a modalias */ 3603a3dd018SBenjamin Herrenschmidt if (!i2c_powermac_get_type(adap, node, addr, 3613a3dd018SBenjamin Herrenschmidt info.type, sizeof(info.type))) { 36281e5d864SBenjamin Herrenschmidt continue; 36381e5d864SBenjamin Herrenschmidt } 36481e5d864SBenjamin Herrenschmidt 36581e5d864SBenjamin Herrenschmidt /* Fill out the rest of the info structure */ 3663a3dd018SBenjamin Herrenschmidt info.addr = addr; 36781e5d864SBenjamin Herrenschmidt info.irq = irq_of_parse_and_map(node, 0); 36881e5d864SBenjamin Herrenschmidt info.of_node = of_node_get(node); 36981e5d864SBenjamin Herrenschmidt 37081e5d864SBenjamin Herrenschmidt newdev = i2c_new_device(adap, &info); 37181e5d864SBenjamin Herrenschmidt if (!newdev) { 37281e5d864SBenjamin Herrenschmidt dev_err(&adap->dev, "i2c-powermac: Failure to register" 373*453a237cSRob Herring " %pOF\n", node); 37481e5d864SBenjamin Herrenschmidt of_node_put(node); 37581e5d864SBenjamin Herrenschmidt /* We do not dispose of the interrupt mapping on 37681e5d864SBenjamin Herrenschmidt * purpose. It's not necessary (interrupt cannot be 37781e5d864SBenjamin Herrenschmidt * re-used) and somebody else might have grabbed it 37881e5d864SBenjamin Herrenschmidt * via direct DT lookup so let's not bother 37981e5d864SBenjamin Herrenschmidt */ 38081e5d864SBenjamin Herrenschmidt continue; 38181e5d864SBenjamin Herrenschmidt } 38281e5d864SBenjamin Herrenschmidt } 3833a3dd018SBenjamin Herrenschmidt 3843a3dd018SBenjamin Herrenschmidt /* Additional workarounds */ 3853a3dd018SBenjamin Herrenschmidt i2c_powermac_add_missing(adap, bus, found_onyx); 38681e5d864SBenjamin Herrenschmidt } 387a28d3af2SBenjamin Herrenschmidt 3880b255e92SBill Pemberton static int i2c_powermac_probe(struct platform_device *dev) 389a28d3af2SBenjamin Herrenschmidt { 3906d4028c6SJingoo Han struct pmac_i2c_bus *bus = dev_get_platdata(&dev->dev); 391a28d3af2SBenjamin Herrenschmidt struct device_node *parent = NULL; 392a28d3af2SBenjamin Herrenschmidt struct i2c_adapter *adapter; 393018a3d1dSJeremy Kerr const char *basename; 394a28d3af2SBenjamin Herrenschmidt int rc; 395a28d3af2SBenjamin Herrenschmidt 396a28d3af2SBenjamin Herrenschmidt if (bus == NULL) 397a28d3af2SBenjamin Herrenschmidt return -EINVAL; 398bc6286e5SJean Delvare adapter = pmac_i2c_get_adapter(bus); 399a28d3af2SBenjamin Herrenschmidt 400a28d3af2SBenjamin Herrenschmidt /* Ok, now we need to make up a name for the interface that will 401a28d3af2SBenjamin Herrenschmidt * match what we used to do in the past, that is basically the 402a28d3af2SBenjamin Herrenschmidt * controller's parent device node for keywest. PMU didn't have a 403a28d3af2SBenjamin Herrenschmidt * naming convention and SMU has a different one 404a28d3af2SBenjamin Herrenschmidt */ 405a28d3af2SBenjamin Herrenschmidt switch(pmac_i2c_get_type(bus)) { 406a28d3af2SBenjamin Herrenschmidt case pmac_i2c_bus_keywest: 407a28d3af2SBenjamin Herrenschmidt parent = of_get_parent(pmac_i2c_get_controller(bus)); 408a28d3af2SBenjamin Herrenschmidt if (parent == NULL) 409a28d3af2SBenjamin Herrenschmidt return -EINVAL; 410a28d3af2SBenjamin Herrenschmidt basename = parent->name; 411a28d3af2SBenjamin Herrenschmidt break; 412a28d3af2SBenjamin Herrenschmidt case pmac_i2c_bus_pmu: 413a28d3af2SBenjamin Herrenschmidt basename = "pmu"; 414a28d3af2SBenjamin Herrenschmidt break; 415a28d3af2SBenjamin Herrenschmidt case pmac_i2c_bus_smu: 416a28d3af2SBenjamin Herrenschmidt /* This is not what we used to do but I'm fixing drivers at 417a28d3af2SBenjamin Herrenschmidt * the same time as this change 418a28d3af2SBenjamin Herrenschmidt */ 419a28d3af2SBenjamin Herrenschmidt basename = "smu"; 420a28d3af2SBenjamin Herrenschmidt break; 421a28d3af2SBenjamin Herrenschmidt default: 422a28d3af2SBenjamin Herrenschmidt return -EINVAL; 423a28d3af2SBenjamin Herrenschmidt } 424bc6286e5SJean Delvare snprintf(adapter->name, sizeof(adapter->name), "%s %d", basename, 425bc6286e5SJean Delvare pmac_i2c_get_channel(bus)); 426a28d3af2SBenjamin Herrenschmidt of_node_put(parent); 427a28d3af2SBenjamin Herrenschmidt 4289f2545c1SBenjamin Herrenschmidt platform_set_drvdata(dev, adapter); 429a28d3af2SBenjamin Herrenschmidt adapter->algo = &i2c_powermac_algorithm; 4307ee405eaSWolfram Sang adapter->quirks = &i2c_powermac_quirks; 431a28d3af2SBenjamin Herrenschmidt i2c_set_adapdata(adapter, bus); 4329f2545c1SBenjamin Herrenschmidt adapter->dev.parent = &dev->dev; 433687b81d0SWolfram Sang 434687b81d0SWolfram Sang /* Clear of_node to skip automatic registration of i2c child nodes */ 435687b81d0SWolfram Sang adapter->dev.of_node = NULL; 436a28d3af2SBenjamin Herrenschmidt rc = i2c_add_adapter(adapter); 437a28d3af2SBenjamin Herrenschmidt if (rc) { 438a28d3af2SBenjamin Herrenschmidt printk(KERN_ERR "i2c-powermac: Adapter %s registration " 439bc6286e5SJean Delvare "failed\n", adapter->name); 4406dfa5ca3SJean Delvare memset(adapter, 0, sizeof(*adapter)); 441874e955bSWolfram Sang return rc; 442a28d3af2SBenjamin Herrenschmidt } 443a28d3af2SBenjamin Herrenschmidt 444bc6286e5SJean Delvare printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name); 445810ad7b6SJean Delvare 446687b81d0SWolfram Sang /* Use custom child registration due to Apple device-tree funkyness */ 447687b81d0SWolfram Sang adapter->dev.of_node = dev->dev.of_node; 44881e5d864SBenjamin Herrenschmidt i2c_powermac_register_devices(adapter, bus); 449810ad7b6SJean Delvare 450874e955bSWolfram Sang return 0; 451a28d3af2SBenjamin Herrenschmidt } 452a28d3af2SBenjamin Herrenschmidt 4539f2545c1SBenjamin Herrenschmidt static struct platform_driver i2c_powermac_driver = { 4549f2545c1SBenjamin Herrenschmidt .probe = i2c_powermac_probe, 4550b255e92SBill Pemberton .remove = i2c_powermac_remove, 4569f2545c1SBenjamin Herrenschmidt .driver = { 457a28d3af2SBenjamin Herrenschmidt .name = "i2c-powermac", 458a28d3af2SBenjamin Herrenschmidt .bus = &platform_bus_type, 4599f2545c1SBenjamin Herrenschmidt }, 460a28d3af2SBenjamin Herrenschmidt }; 461a28d3af2SBenjamin Herrenschmidt 462a3664b51SAxel Lin module_platform_driver(i2c_powermac_driver); 463a28d3af2SBenjamin Herrenschmidt 464a3664b51SAxel Lin MODULE_ALIAS("platform:i2c-powermac"); 465