Skip to contentSkip to conversation

mfd: WM8350 updates

PATCH In review Mark Brown 2 participants 6 messages Nov 6, 2008 – Nov 8, 2008

Subsystems (2)
lore
Share & tools
lore

Mark Brown

author
#0 lore raw

cover mfd: WM8350 updates

The following changes since commit c3177623edf3fabf200c60bde9b400d03b6271f7:
Mark Brown (1):
mfd: Don't mark WM8350 security register as volatile

are available in the git repository at:

git://opensource.wolfsonmicro.com/linux-2.6-audioplus for-sameo

Mark Brown (4):
mfd: Remove i.MX31ism from WM8350 i2c driver
mfd: Add some documentation for WM8350 register lock
mfd: Add WM8350 revision H support
mfd: Add AUXADC support for WM8350

 drivers/mfd/wm8350-core.c             |   74 ++++++++++++++++++++++++++++++++-
 drivers/mfd/wm8350-i2c.c              |    2 -
 include/linux/mfd/wm8350/comparator.h |    8 ++++
 include/linux/mfd/wm8350/core.h       |    3 +
 4 files changed, 83 insertions(+), 4 deletions(-)
author
#1 lore raw

PATCH 1/4 mfd: Remove i.MX31ism from WM8350 i2c driver

---
 drivers/mfd/wm8350-i2c.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/mfd/wm8350-i2c.c +0 -2
index 8dfe21b..f7e9172 100644
@@ -1,8 +1,6 @@
 /*
  * wm8350-i2c.c  --  Generic I2C driver for Wolfson WM8350 PMIC
  *
- * This driver defines and configures the WM8350 for the Freescale i.MX32ADS.
- *
  * Copyright 2007, 2008 Wolfson Microelectronics PLC.
  *
  * Author: Liam Girdwood
Signature · 1 line
1.5.6.5
author
#2 lore raw

PATCH 2/4 mfd: Add some documentation for WM8350 register lock

Hopefully this will make the purpose of these functions a bit clearer, it's not immediately obvious that the lock is a hardware feature.

---
 drivers/mfd/wm8350-core.c |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)
drivers/mfd/wm8350-core.c +16 -0
index 0d47fb9..d63a530 100644
@@ -299,6 +299,13 @@ int wm8350_block_write(struct wm8350 *wm8350, int start_reg, int regs,
 }
 EXPORT_SYMBOL_GPL(wm8350_block_write);
 
+/**
+ * wm8350_reg_lock()
+ *
+ * The WM8350 has a hardware lock which can be used to prevent writes to
+ * some registers (generally those which can cause particularly serious
+ * problems if misused).  This function enables that lock.
+ */
 int wm8350_reg_lock(struct wm8350 *wm8350)
 {
 	u16 key = WM8350_LOCK_KEY;
@@ -314,6 +321,15 @@ int wm8350_reg_lock(struct wm8350 *wm8350)
 }
 EXPORT_SYMBOL_GPL(wm8350_reg_lock);
 
+/**
+ * wm8350_reg_unlock()
+ *
+ * The WM8350 has a hardware lock which can be used to prevent writes to
+ * some registers (generally those which can cause particularly serious
+ * problems if misused).  This function disables that lock so updates
+ * can be performed.  For maximum safety this should be done only when
+ * required.
+ */
 int wm8350_reg_unlock(struct wm8350 *wm8350)
 {
 	u16 key = WM8350_UNLOCK_KEY;
Signature · 1 line
1.5.6.5
author
#3 lore raw

PATCH 3/4 mfd: Add WM8350 revision H support

No other software changes are required.

---
 drivers/mfd/wm8350-core.c       |    7 ++++++-
 include/linux/mfd/wm8350/core.h |    1 +
 2 files changed, 7 insertions(+), 1 deletions(-)
drivers/mfd/wm8350-core.c +6 -1
index d63a530..c013afd 100644
@@ -1202,9 +1202,14 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
 			dev_info(wm8350->dev, "Found Rev G device\n");
 			wm8350->rev = WM8350_REV_G;
 			break;
+		case WM8350_REV_H:
+			dev_info(wm8350->dev, "Found Rev H device\n");
+			wm8350->rev = WM8350_REV_H;
+			break;
 		default:
 			/* For safety we refuse to run on unknown hardware */
-			dev_info(wm8350->dev, "Found unknown rev\n");
+			dev_info(wm8350->dev, "Found unknown rev %x\n",
+				 (id2 & WM8350_CHIP_REV_MASK) >> 12);
 			ret = -ENODEV;
 			goto err;
 		}
include/linux/mfd/wm8350/core.h +1 -0
index 6ebf97f..9490ec1 100644
@@ -536,6 +536,7 @@
 #define WM8350_REV_E				0x4
 #define WM8350_REV_F				0x5
 #define WM8350_REV_G				0x6
+#define WM8350_REV_H				0x7
 
 #define WM8350_NUM_IRQ				63
 
Signature · 1 line
1.5.6.5
author
#4 lore raw

PATCH 4/4 mfd: Add AUXADC support for WM8350

The auxiliary ADC in the WM8350 is shared between several subdevices so access to it needs to be arbitrated by the core driver.

---
 drivers/mfd/wm8350-core.c             |   51 ++++++++++++++++++++++++++++++++-
 include/linux/mfd/wm8350/comparator.h |    8 +++++
 include/linux/mfd/wm8350/core.h       |    2 +
 3 files changed, 60 insertions(+), 1 deletions(-)
drivers/mfd/wm8350-core.c +50 -1
index c013afd..60439bd 100644
@@ -63,7 +63,6 @@
  */
 static DEFINE_MUTEX(io_mutex);
 static DEFINE_MUTEX(reg_lock_mutex);
-static DEFINE_MUTEX(auxadc_mutex);
 
 /* Perform a physical read from the device.
  */
@@ -1082,6 +1081,55 @@ int wm8350_unmask_irq(struct wm8350 *wm8350, int irq)
 }
 EXPORT_SYMBOL_GPL(wm8350_unmask_irq);
 
+int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
+{
+	u16 reg, result = 0;
+	int tries = 5;
+
+	if (channel < WM8350_AUXADC_AUX1 || channel > WM8350_AUXADC_TEMP)
+		return -EINVAL;
+	if (channel >= WM8350_AUXADC_USB && channel <= WM8350_AUXADC_TEMP
+	    && (scale != 0 || vref != 0))
+		return -EINVAL;
+
+	mutex_lock(&wm8350->auxadc_mutex);
+
+	/* Turn on the ADC */
+	reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
+	wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5, reg | WM8350_AUXADC_ENA);
+
+	if (scale || vref) {
+		reg = scale << 13;
+		reg |= vref << 12;
+		wm8350_reg_write(wm8350, WM8350_AUX1_READBACK + channel, reg);
+	}
+
+	reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
+	reg |= 1 << channel | WM8350_AUXADC_POLL;
+	wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_1, reg);
+
+	do {
+		schedule_timeout_interruptible(1);
+		reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
+	} while (tries-- && (reg & WM8350_AUXADC_POLL));
+
+	if (!tries)
+		dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
+	else
+		result = wm8350_reg_read(wm8350,
+					 WM8350_AUX1_READBACK + channel);
+
+	/* Turn off the ADC */
+	reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5);
+	wm8350_reg_write(wm8350, WM8350_POWER_MGMT_5,
+			 reg & ~WM8350_AUXADC_ENA);
+
+	mutex_unlock(&wm8350->auxadc_mutex);
+
+	return result & WM8350_AUXADC_DATA1_MASK;
+}
+EXPORT_SYMBOL_GPL(wm8350_read_auxadc);
+
 /*
  * Cache is always host endian.
  */
@@ -1239,6 +1287,7 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
 		}
 	}
 
+	mutex_init(&wm8350->auxadc_mutex);
 	mutex_init(&wm8350->irq_mutex);
 	INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
 	if (irq) {
include/linux/mfd/wm8350/comparator.h +8 -0
index 0537886..54bc5d0 100644
@@ -164,4 +164,12 @@
 #define WM8350_AUXADC_BATT			6
 #define WM8350_AUXADC_TEMP			7
 
+struct wm8350;
+
+/*
+ * AUX ADC Readback
+ */
+int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale,
+		       int vref);
+
 #endif
include/linux/mfd/wm8350/core.h +2 -0
index 9490ec1..cc19005 100644
@@ -573,6 +573,8 @@ struct wm8350 {
 			 void *src);
 	u16 *reg_cache;
 
+	struct mutex auxadc_mutex;
+
 	/* Interrupt handling */
 	struct work_struct irq_work;
 	struct mutex irq_mutex; /* IRQ table mutex */
Signature · 1 line
1.5.6.5
#5 lore raw
In reply to Mark Brown
Quoted 3 lines · Mark Brown

The following changes since commit c3177623edf3fabf200c60bde9b400d03b6271f7:
Mark Brown (1):
mfd: Don't mark WM8350 security register as volatile

Pulled into my for-next branch, thanks Mark.

Cheers,
Samuel.

Quoted 15 lines

are available in the git repository at:

git://opensource.wolfsonmicro.com/linux-2.6-audioplus for-sameo

Mark Brown (4):
mfd: Remove i.MX31ism from WM8350 i2c driver
mfd: Add some documentation for WM8350 register lock
mfd: Add WM8350 revision H support
mfd: Add AUXADC support for WM8350

 drivers/mfd/wm8350-core.c             |   74 ++++++++++++++++++++++++++++++++-
 drivers/mfd/wm8350-i2c.c              |    2 -
 include/linux/mfd/wm8350/comparator.h |    8 ++++
 include/linux/mfd/wm8350/core.h       |    3 +
 4 files changed, 83 insertions(+), 4 deletions(-)
Signature · 2 lines
Intel Open Source Technology Centre
http://oss.intel.com/