diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-05 17:36:20 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-05 17:36:20 -0700 | 
| commit | d7ab7302f970a254997687a1cdede421a5635c68 (patch) | |
| tree | 71341b72e81c8e031b98e8115c51682427192798 /drivers/mfd/retu-mfd.c | |
| parent | 01227a889ed56ae53aeebb9f93be9d54dd8b2de8 (diff) | |
| parent | 99f4c6b66a9ae362d21e6df95d04bc74e04d285e (diff) | |
| download | olio-linux-3.10-d7ab7302f970a254997687a1cdede421a5635c68.tar.xz olio-linux-3.10-d7ab7302f970a254997687a1cdede421a5635c68.zip  | |
Merge tag 'mfd-3.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next
Pull MFD update from Samuel Ortiz:
 "For 3.10 we have a few new MFD drivers for:
   - The ChromeOS embedded controller which provides keyboard, battery
     and power management services.  This controller is accessible
     through i2c or SPI.
   - Silicon Laboratories 476x controller, providing access to their FM
     chipset and their audio codec.
   - Realtek's RTS5249, a memory stick, MMC and SD/SDIO PCI based
     reader.
   - Nokia's Tahvo power button and watchdog device.  This device is
     very similar to Retu and is thus supported by the same code base.
   - STMicroelectronics STMPE1801, a keyboard and GPIO controller
     supported by the stmpe driver.
   - ST-Ericsson AB8540 and AB8505 power management and voltage
     converter controllers through the existing ab8500 code.
  Some other drivers got cleaned up or improved.  In particular:
   - The Linaro/STE guys got the ab8500 driver in sync with their
     internal code through a series of optimizations, fixes and
     improvements.
   - The AS3711 and OMAP USB drivers now have DT support.
   - The arizona clock and interrupt handling code got improved.
   - The wm5102 register patch and boot mechanism also got improved."
* tag 'mfd-3.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next: (104 commits)
  mfd: si476x: Don't use 0bNNN
  mfd: vexpress: Handle pending config transactions
  mfd: ab8500: Export ab8500_gpadc_sw_hw_convert properly
  mfd: si476x: Fix i2c warning
  mfd: si476x: Add header files and Kbuild plumbing
  mfd: si476x: Add chip properties handling code
  mfd: si476x: Add the bulk of the core driver
  mfd: si476x: Add commands abstraction layer
  mfd: rtsx: Support RTS5249
  mfd: retu: Add Tahvo support
  mfd: ucb1400: Pass ucb1400-gpio data through ac97 bus
  mfd: wm8994: Add some OF properties
  mfd: wm8994: Add device ID data to WM8994 OF device IDs
  input: Export matrix_keypad_parse_of_params()
  mfd: tps65090: Add compatible string for charger subnode
  mfd: db8500-prcmu: Support platform dependant device selection
  mfd: syscon: Fix warnings when printing resource_size_t
  of: Add stub of_get_parent for non-OF builds
  mfd: omap-usb-tll: Convert to devm_ioremap_resource()
  mfd: omap-usb-host: Convert to devm_ioremap_resource()
  ...
Diffstat (limited to 'drivers/mfd/retu-mfd.c')
| -rw-r--r-- | drivers/mfd/retu-mfd.c | 85 | 
1 files changed, 75 insertions, 10 deletions
diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c index 3ba048655bf..a1830986eeb 100644 --- a/drivers/mfd/retu-mfd.c +++ b/drivers/mfd/retu-mfd.c @@ -1,5 +1,5 @@  /* - * Retu MFD driver + * Retu/Tahvo MFD driver   *   * Copyright (C) 2004, 2005 Nokia Corporation   * @@ -33,7 +33,8 @@  #define RETU_REG_ASICR		0x00		/* ASIC ID and revision */  #define RETU_REG_ASICR_VILMA	(1 << 7)	/* Bit indicating Vilma */  #define RETU_REG_IDR		0x01		/* Interrupt ID */ -#define RETU_REG_IMR		0x02		/* Interrupt mask */ +#define RETU_REG_IMR		0x02		/* Interrupt mask (Retu) */ +#define TAHVO_REG_IMR		0x03		/* Interrupt mask (Tahvo) */  /* Interrupt sources */  #define RETU_INT_PWR		0		/* Power button */ @@ -84,6 +85,62 @@ static struct regmap_irq_chip retu_irq_chip = {  /* Retu device registered for the power off. */  static struct retu_dev *retu_pm_power_off; +static struct resource tahvo_usb_res[] = { +	{ +		.name	= "tahvo-usb", +		.start	= TAHVO_INT_VBUS, +		.end	= TAHVO_INT_VBUS, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct mfd_cell tahvo_devs[] = { +	{ +		.name		= "tahvo-usb", +		.resources	= tahvo_usb_res, +		.num_resources	= ARRAY_SIZE(tahvo_usb_res), +	}, +}; + +static struct regmap_irq tahvo_irqs[] = { +	[TAHVO_INT_VBUS] = { +		.mask = 1 << TAHVO_INT_VBUS, +	} +}; + +static struct regmap_irq_chip tahvo_irq_chip = { +	.name		= "TAHVO", +	.irqs		= tahvo_irqs, +	.num_irqs	= ARRAY_SIZE(tahvo_irqs), +	.num_regs	= 1, +	.status_base	= RETU_REG_IDR, +	.mask_base	= TAHVO_REG_IMR, +	.ack_base	= RETU_REG_IDR, +}; + +static const struct retu_data { +	char			*chip_name; +	char			*companion_name; +	struct regmap_irq_chip	*irq_chip; +	struct mfd_cell		*children; +	int			nchildren; +} retu_data[] = { +	[0] = { +		.chip_name	= "Retu", +		.companion_name	= "Vilma", +		.irq_chip	= &retu_irq_chip, +		.children	= retu_devs, +		.nchildren	= ARRAY_SIZE(retu_devs), +	}, +	[1] = { +		.chip_name	= "Tahvo", +		.companion_name	= "Betty", +		.irq_chip	= &tahvo_irq_chip, +		.children	= tahvo_devs, +		.nchildren	= ARRAY_SIZE(tahvo_devs), +	} +}; +  int retu_read(struct retu_dev *rdev, u8 reg)  {  	int ret; @@ -173,9 +230,14 @@ static struct regmap_config retu_config = {  static int retu_probe(struct i2c_client *i2c, const struct i2c_device_id *id)  { +	struct retu_data const *rdat;  	struct retu_dev *rdev;  	int ret; +	if (i2c->addr > ARRAY_SIZE(retu_data)) +		return -ENODEV; +	rdat = &retu_data[i2c->addr - 1]; +  	rdev = devm_kzalloc(&i2c->dev, sizeof(*rdev), GFP_KERNEL);  	if (rdev == NULL)  		return -ENOMEM; @@ -190,25 +252,27 @@ static int retu_probe(struct i2c_client *i2c, const struct i2c_device_id *id)  	ret = retu_read(rdev, RETU_REG_ASICR);  	if (ret < 0) { -		dev_err(rdev->dev, "could not read Retu revision: %d\n", ret); +		dev_err(rdev->dev, "could not read %s revision: %d\n", +			rdat->chip_name, ret);  		return ret;  	} -	dev_info(rdev->dev, "Retu%s v%d.%d found\n", -		 (ret & RETU_REG_ASICR_VILMA) ? " & Vilma" : "", +	dev_info(rdev->dev, "%s%s%s v%d.%d found\n", rdat->chip_name, +		 (ret & RETU_REG_ASICR_VILMA) ? " & " : "", +		 (ret & RETU_REG_ASICR_VILMA) ? rdat->companion_name : "",  		 (ret >> 4) & 0x7, ret & 0xf); -	/* Mask all RETU interrupts. */ -	ret = retu_write(rdev, RETU_REG_IMR, 0xffff); +	/* Mask all interrupts. */ +	ret = retu_write(rdev, rdat->irq_chip->mask_base, 0xffff);  	if (ret < 0)  		return ret;  	ret = regmap_add_irq_chip(rdev->regmap, i2c->irq, IRQF_ONESHOT, -1, -				  &retu_irq_chip, &rdev->irq_data); +				  rdat->irq_chip, &rdev->irq_data);  	if (ret < 0)  		return ret; -	ret = mfd_add_devices(rdev->dev, -1, retu_devs, ARRAY_SIZE(retu_devs), +	ret = mfd_add_devices(rdev->dev, -1, rdat->children, rdat->nchildren,  			      NULL, regmap_irq_chip_get_base(rdev->irq_data),  			      NULL);  	if (ret < 0) { @@ -216,7 +280,7 @@ static int retu_probe(struct i2c_client *i2c, const struct i2c_device_id *id)  		return ret;  	} -	if (!pm_power_off) { +	if (i2c->addr == 1 && !pm_power_off) {  		retu_pm_power_off = rdev;  		pm_power_off	  = retu_power_off;  	} @@ -240,6 +304,7 @@ static int retu_remove(struct i2c_client *i2c)  static const struct i2c_device_id retu_id[] = {  	{ "retu-mfd", 0 }, +	{ "tahvo-mfd", 0 },  	{ }  };  MODULE_DEVICE_TABLE(i2c, retu_id);  |