aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac/low_i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/powermac/low_i2c.c')
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c294
1 files changed, 292 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index a25e447f907..535c802b369 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -49,6 +49,7 @@
49#include <asm/prom.h> 49#include <asm/prom.h>
50#include <asm/machdep.h> 50#include <asm/machdep.h>
51#include <asm/smu.h> 51#include <asm/smu.h>
52#include <asm/pmac_pfunc.h>
52#include <asm/pmac_low_i2c.h> 53#include <asm/pmac_low_i2c.h>
53 54
54#ifdef DEBUG 55#ifdef DEBUG
@@ -1162,9 +1163,291 @@ int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
1162} 1163}
1163EXPORT_SYMBOL_GPL(pmac_i2c_xfer); 1164EXPORT_SYMBOL_GPL(pmac_i2c_xfer);
1164 1165
1166/* some quirks for platform function decoding */
1167enum {
1168 pmac_i2c_quirk_invmask = 0x00000001u,
1169};
1170
1171static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
1172 int quirks))
1173{
1174 struct pmac_i2c_bus *bus;
1175 struct device_node *np;
1176 static struct whitelist_ent {
1177 char *name;
1178 char *compatible;
1179 int quirks;
1180 } whitelist[] = {
1181 /* XXX Study device-tree's & apple drivers are get the quirks
1182 * right !
1183 */
1184 { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask },
1185 { "i2c-cpu-voltage", NULL, 0},
1186 { "temp-monitor", NULL, 0 },
1187 { "supply-monitor", NULL, 0 },
1188 { NULL, NULL, 0 },
1189 };
1190
1191 /* Only some devices need to have platform functions instanciated
1192 * here. For now, we have a table. Others, like 9554 i2c GPIOs used
1193 * on Xserve, if we ever do a driver for them, will use their own
1194 * platform function instance
1195 */
1196 list_for_each_entry(bus, &pmac_i2c_busses, link) {
1197 for (np = NULL;
1198 (np = of_get_next_child(bus->busnode, np)) != NULL;) {
1199 struct whitelist_ent *p;
1200 /* If multibus, check if device is on that bus */
1201 if (bus->flags & pmac_i2c_multibus)
1202 if (bus != pmac_i2c_find_bus(np))
1203 continue;
1204 for (p = whitelist; p->name != NULL; p++) {
1205 if (strcmp(np->name, p->name))
1206 continue;
1207 if (p->compatible &&
1208 !device_is_compatible(np, p->compatible))
1209 continue;
1210 callback(np, p->quirks);
1211 break;
1212 }
1213 }
1214 }
1215}
1216
1217#define MAX_I2C_DATA 64
1218
1219struct pmac_i2c_pf_inst
1220{
1221 struct pmac_i2c_bus *bus;
1222 u8 addr;
1223 u8 buffer[MAX_I2C_DATA];
1224 u8 scratch[MAX_I2C_DATA];
1225 int bytes;
1226 int quirks;
1227};
1228
1229static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args)
1230{
1231 struct pmac_i2c_pf_inst *inst;
1232 struct pmac_i2c_bus *bus;
1233
1234 bus = pmac_i2c_find_bus(func->node);
1235 if (bus == NULL) {
1236 printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n",
1237 func->node->full_name);
1238 return NULL;
1239 }
1240 if (pmac_i2c_open(bus, 0)) {
1241 printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n",
1242 func->node->full_name);
1243 return NULL;
1244 }
1245
1246 /* XXX might need GFP_ATOMIC when called during the suspend process,
1247 * but then, there are already lots of issues with suspending when
1248 * near OOM that need to be resolved, the allocator itself should
1249 * probably make GFP_NOIO implicit during suspend
1250 */
1251 inst = kzalloc(sizeof(struct pmac_i2c_pf_inst), GFP_KERNEL);
1252 if (inst == NULL) {
1253 pmac_i2c_close(bus);
1254 return NULL;
1255 }
1256 inst->bus = bus;
1257 inst->addr = pmac_i2c_get_dev_addr(func->node);
1258 inst->quirks = (int)(long)func->driver_data;
1259 return inst;
1260}
1261
1262static void pmac_i2c_do_end(struct pmf_function *func, void *instdata)
1263{
1264 struct pmac_i2c_pf_inst *inst = instdata;
1265
1266 if (inst == NULL)
1267 return;
1268 pmac_i2c_close(inst->bus);
1269 if (inst)
1270 kfree(inst);
1271}
1272
1273static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len)
1274{
1275 struct pmac_i2c_pf_inst *inst = instdata;
1276
1277 inst->bytes = len;
1278 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 0, 0,
1279 inst->buffer, len);
1280}
1281
1282static int pmac_i2c_do_write(PMF_STD_ARGS, u32 len, const u8 *data)
1283{
1284 struct pmac_i2c_pf_inst *inst = instdata;
1285
1286 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
1287 (u8 *)data, len);
1288}
1289
1290/* This function is used to do the masking & OR'ing for the "rmw" type
1291 * callbacks. Ze should apply the mask and OR in the values in the
1292 * buffer before writing back. The problem is that it seems that
1293 * various darwin drivers implement the mask/or differently, thus
1294 * we need to check the quirks first
1295 */
1296static void pmac_i2c_do_apply_rmw(struct pmac_i2c_pf_inst *inst,
1297 u32 len, const u8 *mask, const u8 *val)
1298{
1299 int i;
1300
1301 if (inst->quirks & pmac_i2c_quirk_invmask) {
1302 for (i = 0; i < len; i ++)
1303 inst->scratch[i] = (inst->buffer[i] & mask[i]) | val[i];
1304 } else {
1305 for (i = 0; i < len; i ++)
1306 inst->scratch[i] = (inst->buffer[i] & ~mask[i])
1307 | (val[i] & mask[i]);
1308 }
1309}
1310
1311static int pmac_i2c_do_rmw(PMF_STD_ARGS, u32 masklen, u32 valuelen,
1312 u32 totallen, const u8 *maskdata,
1313 const u8 *valuedata)
1314{
1315 struct pmac_i2c_pf_inst *inst = instdata;
1316
1317 if (masklen > inst->bytes || valuelen > inst->bytes ||
1318 totallen > inst->bytes || valuelen > masklen)
1319 return -EINVAL;
1320
1321 pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
1322
1323 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
1324 inst->scratch, totallen);
1325}
1326
1327static int pmac_i2c_do_read_sub(PMF_STD_ARGS, u8 subaddr, u32 len)
1328{
1329 struct pmac_i2c_pf_inst *inst = instdata;
1330
1331 inst->bytes = len;
1332 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 1, subaddr,
1333 inst->buffer, len);
1334}
1335
1336static int pmac_i2c_do_write_sub(PMF_STD_ARGS, u8 subaddr, u32 len,
1337 const u8 *data)
1338{
1339 struct pmac_i2c_pf_inst *inst = instdata;
1340
1341 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
1342 subaddr, (u8 *)data, len);
1343}
1344
1345static int pmac_i2c_do_set_mode(PMF_STD_ARGS, int mode)
1346{
1347 struct pmac_i2c_pf_inst *inst = instdata;
1348
1349 return pmac_i2c_setmode(inst->bus, mode);
1350}
1351
1352static int pmac_i2c_do_rmw_sub(PMF_STD_ARGS, u8 subaddr, u32 masklen,
1353 u32 valuelen, u32 totallen, const u8 *maskdata,
1354 const u8 *valuedata)
1355{
1356 struct pmac_i2c_pf_inst *inst = instdata;
1357
1358 if (masklen > inst->bytes || valuelen > inst->bytes ||
1359 totallen > inst->bytes || valuelen > masklen)
1360 return -EINVAL;
1361
1362 pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
1363
1364 return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
1365 subaddr, inst->scratch, totallen);
1366}
1367
1368static int pmac_i2c_do_mask_and_comp(PMF_STD_ARGS, u32 len,
1369 const u8 *maskdata,
1370 const u8 *valuedata)
1371{
1372 struct pmac_i2c_pf_inst *inst = instdata;
1373 int i, match;
1374
1375 /* Get return value pointer, it's assumed to be a u32 */
1376 if (!args || !args->count || !args->u[0].p)
1377 return -EINVAL;
1378
1379 /* Check buffer */
1380 if (len > inst->bytes)
1381 return -EINVAL;
1382
1383 for (i = 0, match = 1; match && i < len; i ++)
1384 if ((inst->buffer[i] & maskdata[i]) != valuedata[i])
1385 match = 0;
1386 *args->u[0].p = match;
1387 return 0;
1388}
1389
1390static int pmac_i2c_do_delay(PMF_STD_ARGS, u32 duration)
1391{
1392 msleep((duration + 999) / 1000);
1393 return 0;
1394}
1395
1396
1397static struct pmf_handlers pmac_i2c_pfunc_handlers = {
1398 .begin = pmac_i2c_do_begin,
1399 .end = pmac_i2c_do_end,
1400 .read_i2c = pmac_i2c_do_read,
1401 .write_i2c = pmac_i2c_do_write,
1402 .rmw_i2c = pmac_i2c_do_rmw,
1403 .read_i2c_sub = pmac_i2c_do_read_sub,
1404 .write_i2c_sub = pmac_i2c_do_write_sub,
1405 .rmw_i2c_sub = pmac_i2c_do_rmw_sub,
1406 .set_i2c_mode = pmac_i2c_do_set_mode,
1407 .mask_and_compare = pmac_i2c_do_mask_and_comp,
1408 .delay = pmac_i2c_do_delay,
1409};
1410
1411static void __init pmac_i2c_dev_create(struct device_node *np, int quirks)
1412{
1413 DBG("dev_create(%s)\n", np->full_name);
1414
1415 pmf_register_driver(np, &pmac_i2c_pfunc_handlers,
1416 (void *)(long)quirks);
1417}
1418
1419static void __init pmac_i2c_dev_init(struct device_node *np, int quirks)
1420{
1421 DBG("dev_create(%s)\n", np->full_name);
1422
1423 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
1424}
1425
1426static void pmac_i2c_dev_suspend(struct device_node *np, int quirks)
1427{
1428 DBG("dev_suspend(%s)\n", np->full_name);
1429 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL);
1430}
1431
1432static void pmac_i2c_dev_resume(struct device_node *np, int quirks)
1433{
1434 DBG("dev_resume(%s)\n", np->full_name);
1435 pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL);
1436}
1437
1438void pmac_pfunc_i2c_suspend(void)
1439{
1440 pmac_i2c_devscan(pmac_i2c_dev_suspend);
1441}
1442
1443void pmac_pfunc_i2c_resume(void)
1444{
1445 pmac_i2c_devscan(pmac_i2c_dev_resume);
1446}
1447
1165/* 1448/*
1166 * Initialize us: probe all i2c busses on the machine and instantiate 1449 * Initialize us: probe all i2c busses on the machine, instantiate
1167 * busses. 1450 * busses and platform functions as needed.
1168 */ 1451 */
1169/* This is non-static as it might be called early by smp code */ 1452/* This is non-static as it might be called early by smp code */
1170int __init pmac_i2c_init(void) 1453int __init pmac_i2c_init(void)
@@ -1187,6 +1470,10 @@ int __init pmac_i2c_init(void)
1187 /* Probe SMU i2c busses */ 1470 /* Probe SMU i2c busses */
1188 smu_i2c_probe(); 1471 smu_i2c_probe();
1189#endif 1472#endif
1473
1474 /* Now add plaform functions for some known devices */
1475 pmac_i2c_devscan(pmac_i2c_dev_create);
1476
1190 return 0; 1477 return 0;
1191} 1478}
1192arch_initcall(pmac_i2c_init); 1479arch_initcall(pmac_i2c_init);
@@ -1216,6 +1503,9 @@ static int __init pmac_i2c_create_platform_devices(void)
1216 platform_device_add(bus->platform_dev); 1503 platform_device_add(bus->platform_dev);
1217 } 1504 }
1218 1505
1506 /* Now call platform "init" functions */
1507 pmac_i2c_devscan(pmac_i2c_dev_init);
1508
1219 return 0; 1509 return 0;
1220} 1510}
1221subsys_initcall(pmac_i2c_create_platform_devices); 1511subsys_initcall(pmac_i2c_create_platform_devices);