Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.5-rc3 140 lines 3.5 kB view raw
1/* 2 * Copyright 2009-2010 Pengutronix 3 * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> 4 * 5 * loosely based on an earlier driver that has 6 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> 7 * 8 * This program is free software; you can redistribute it and/or modify it under 9 * the terms of the GNU General Public License version 2 as published by the 10 * Free Software Foundation. 11 */ 12 13#include <linux/slab.h> 14#include <linux/module.h> 15#include <linux/platform_device.h> 16#include <linux/mutex.h> 17#include <linux/interrupt.h> 18#include <linux/mfd/core.h> 19#include <linux/mfd/mc13xxx.h> 20#include <linux/of.h> 21#include <linux/of_device.h> 22#include <linux/of_gpio.h> 23#include <linux/err.h> 24#include <linux/spi/spi.h> 25 26#include "mc13xxx.h" 27 28static const struct spi_device_id mc13xxx_device_id[] = { 29 { 30 .name = "mc13783", 31 .driver_data = MC13XXX_ID_MC13783, 32 }, { 33 .name = "mc13892", 34 .driver_data = MC13XXX_ID_MC13892, 35 }, { 36 /* sentinel */ 37 } 38}; 39MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); 40 41static const struct of_device_id mc13xxx_dt_ids[] = { 42 { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, }, 43 { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, }, 44 { /* sentinel */ } 45}; 46MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); 47 48static struct regmap_config mc13xxx_regmap_spi_config = { 49 .reg_bits = 7, 50 .pad_bits = 1, 51 .val_bits = 24, 52 53 .max_register = MC13XXX_NUMREGS, 54 55 .cache_type = REGCACHE_NONE, 56}; 57 58static int mc13xxx_spi_probe(struct spi_device *spi) 59{ 60 const struct of_device_id *of_id; 61 struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); 62 struct mc13xxx *mc13xxx; 63 struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); 64 int ret; 65 66 of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); 67 if (of_id) 68 sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; 69 70 mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); 71 if (!mc13xxx) 72 return -ENOMEM; 73 74 dev_set_drvdata(&spi->dev, mc13xxx); 75 spi->mode = SPI_MODE_0 | SPI_CS_HIGH; 76 spi->bits_per_word = 32; 77 78 mc13xxx->dev = &spi->dev; 79 mutex_init(&mc13xxx->lock); 80 81 mc13xxx->regmap = regmap_init_spi(spi, &mc13xxx_regmap_spi_config); 82 if (IS_ERR(mc13xxx->regmap)) { 83 ret = PTR_ERR(mc13xxx->regmap); 84 dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", 85 ret); 86 dev_set_drvdata(&spi->dev, NULL); 87 kfree(mc13xxx); 88 return ret; 89 } 90 91 ret = mc13xxx_common_init(mc13xxx, pdata, spi->irq); 92 93 if (ret) { 94 dev_set_drvdata(&spi->dev, NULL); 95 } else { 96 const struct spi_device_id *devid = 97 spi_get_device_id(spi); 98 if (!devid || devid->driver_data != mc13xxx->ictype) 99 dev_warn(mc13xxx->dev, 100 "device id doesn't match auto detection!\n"); 101 } 102 103 return ret; 104} 105 106static int __devexit mc13xxx_spi_remove(struct spi_device *spi) 107{ 108 struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); 109 110 mc13xxx_common_cleanup(mc13xxx); 111 112 return 0; 113} 114 115static struct spi_driver mc13xxx_spi_driver = { 116 .id_table = mc13xxx_device_id, 117 .driver = { 118 .name = "mc13xxx", 119 .owner = THIS_MODULE, 120 .of_match_table = mc13xxx_dt_ids, 121 }, 122 .probe = mc13xxx_spi_probe, 123 .remove = __devexit_p(mc13xxx_spi_remove), 124}; 125 126static int __init mc13xxx_init(void) 127{ 128 return spi_register_driver(&mc13xxx_spi_driver); 129} 130subsys_initcall(mc13xxx_init); 131 132static void __exit mc13xxx_exit(void) 133{ 134 spi_unregister_driver(&mc13xxx_spi_driver); 135} 136module_exit(mc13xxx_exit); 137 138MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC"); 139MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); 140MODULE_LICENSE("GPL v2");