* [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-11-24 9:12 [PATCH 1/2] MFD: MAX8997: add platform data for MAX8997 MUIC driver Donggeun Kim
@ 2011-11-24 9:12 ` Donggeun Kim
2011-11-28 23:48 ` Andrew Morton
2011-12-12 17:08 ` Samuel Ortiz
0 siblings, 2 replies; 10+ messages in thread
From: Donggeun Kim @ 2011-11-24 9:12 UTC (permalink / raw)
To: linux-kernel
Cc: sameo, broonie, gregkh, akpm, kyungmin.park, myungjoo.ham,
dg77.kim
The MUIC function in MAX8997 device can be used as
a USB port detector and switch.
This patch supports the MUIC feature of MAX8997.
Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
drivers/misc/Kconfig | 8 +
drivers/misc/Makefile | 1 +
drivers/misc/max8997-muic.c | 634 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 643 insertions(+), 0 deletions(-)
create mode 100644 drivers/misc/max8997-muic.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d593878..a6e4bc3 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -499,6 +499,14 @@ config USB_SWITCH_FSA9480
stereo and mono audio, video, microphone and UART data to use
a common connector port.
+config MAX8997_MUIC
+ tristate "MAX8997 MUIC Support"
+ depends on MFD_MAX8997
+ help
+ If you say yes here you get support for the MUIC device of
+ Maxim MAX8997 PMIC.
+ The MAX8997 MUIC is a USB port accessory detector and switch.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b26495a..3e1d801 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -48,3 +48,4 @@ obj-y += lis3lv02d/
obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
+obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o
diff --git a/drivers/misc/max8997-muic.c b/drivers/misc/max8997-muic.c
new file mode 100644
index 0000000..74a9448
--- /dev/null
+++ b/drivers/misc/max8997-muic.c
@@ -0,0 +1,634 @@
+/*
+ * max8997-muic.c - MAX8997 muic driver for the Maxim 8997
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Donggeun Kim <dg77.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/kobject.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+
+/* MAX8997-MUIC STATUS1 register */
+#define STATUS1_ADC_SHIFT 0
+#define STATUS1_ADCLOW_SHIFT 5
+#define STATUS1_ADCERR_SHIFT 6
+#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
+#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT)
+#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT)
+
+/* MAX8997-MUIC STATUS2 register */
+#define STATUS2_CHGTYP_SHIFT 0
+#define STATUS2_CHGDETRUN_SHIFT 3
+#define STATUS2_DCDTMR_SHIFT 4
+#define STATUS2_DBCHG_SHIFT 5
+#define STATUS2_VBVOLT_SHIFT 6
+#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
+#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT)
+#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT)
+#define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT)
+#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT)
+
+/* MAX8997-MUIC STATUS3 register */
+#define STATUS3_OVP_SHIFT 2
+#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT)
+
+/* MAX8997-MUIC CONTROL1 register */
+#define COMN1SW_SHIFT 0
+#define COMP2SW_SHIFT 3
+#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
+#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
+#define SW_MASK (COMP2SW_MASK | COMN1SW_MASK)
+
+#define MAX8997_SW_USB ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT))
+#define MAX8997_SW_AUDIO ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT))
+#define MAX8997_SW_UART ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT))
+#define MAX8997_SW_OPEN ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT))
+
+#define MAX8997_ADC_GROUND 0x00
+#define MAX8997_ADC_MHL 0x01
+#define MAX8997_ADC_JIG_USB_1 0x18
+#define MAX8997_ADC_JIG_USB_2 0x19
+#define MAX8997_ADC_DESKDOCK 0x1a
+#define MAX8997_ADC_JIG_UART 0x1c
+#define MAX8997_ADC_CARDOCK 0x1d
+#define MAX8997_ADC_OPEN 0x1f
+
+struct max8997_muic_irq {
+ unsigned int irq;
+ const char *name;
+};
+
+static struct max8997_muic_irq muic_irqs[] = {
+ { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" },
+ { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" },
+ { MAX8997_MUICIRQ_ADC, "muic-ADC" },
+ { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" },
+ { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" },
+ { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" },
+ { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" },
+ { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" },
+ { MAX8997_MUICIRQ_OVP, "muic-over_voltage" },
+};
+
+struct max8997_muic_info {
+ struct device *dev;
+ struct max8997_dev *iodev;
+ struct i2c_client *muic;
+ struct max8997_muic_platform_data *muic_pdata;
+
+ int irq;
+ struct work_struct irq_work;
+
+ enum max8997_muic_charger_type pre_charger_type;
+ int pre_adc;
+
+ struct mutex mutex;
+};
+
+static int max8997_muic_handle_usb(struct max8997_muic_info *info,
+ enum max8997_muic_usb_type usb_type, bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int ret = 0;
+
+ if (usb_type == MAX8997_USB_HOST) {
+ /* switch to USB */
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ attached ? MAX8997_SW_USB : MAX8997_SW_OPEN,
+ SW_MASK);
+ if (ret) {
+ dev_err(info->dev, "failed to update muic register\n");
+ goto out;
+ }
+ }
+
+ if (mdata->usb_callback)
+ mdata->usb_callback(usb_type, attached);
+out:
+ return ret;
+}
+
+static void max8997_muic_handle_mhl(struct max8997_muic_info *info,
+ bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+
+ if (mdata->mhl_callback)
+ mdata->mhl_callback(attached);
+}
+
+static int max8997_muic_handle_dock(struct max8997_muic_info *info,
+ int adc, bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int ret = 0;
+
+ /* switch to AUDIO */
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN,
+ SW_MASK);
+ if (ret) {
+ dev_err(info->dev, "failed to update muic register\n");
+ goto out;
+ }
+
+ switch (adc) {
+ case MAX8997_ADC_DESKDOCK:
+ if (mdata->deskdock_callback)
+ mdata->deskdock_callback(attached);
+ break;
+ case MAX8997_ADC_CARDOCK:
+ if (mdata->cardock_callback)
+ mdata->cardock_callback(attached);
+ break;
+ default:
+ break;
+ }
+out:
+ return ret;
+}
+
+static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info,
+ bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int ret = 0;
+
+ /* switch to UART */
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ attached ? MAX8997_SW_UART : MAX8997_SW_OPEN,
+ SW_MASK);
+ if (ret) {
+ dev_err(info->dev, "failed to update muic register\n");
+ goto out;
+ }
+
+ if (mdata->uart_callback)
+ mdata->uart_callback(attached);
+out:
+ return ret;
+}
+
+static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info)
+{
+ int ret = 0;
+
+ switch (info->pre_adc) {
+ case MAX8997_ADC_GROUND:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false);
+ break;
+ case MAX8997_ADC_MHL:
+ max8997_muic_handle_mhl(info, false);
+ break;
+ case MAX8997_ADC_JIG_USB_1:
+ case MAX8997_ADC_JIG_USB_2:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false);
+ break;
+ case MAX8997_ADC_DESKDOCK:
+ case MAX8997_ADC_CARDOCK:
+ ret = max8997_muic_handle_dock(info, info->pre_adc, false);
+ break;
+ case MAX8997_ADC_JIG_UART:
+ ret = max8997_muic_handle_jig_uart(info, false);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc)
+{
+ int ret = 0;
+
+ switch (adc) {
+ case MAX8997_ADC_GROUND:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true);
+ break;
+ case MAX8997_ADC_MHL:
+ max8997_muic_handle_mhl(info, true);
+ break;
+ case MAX8997_ADC_JIG_USB_1:
+ case MAX8997_ADC_JIG_USB_2:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true);
+ break;
+ case MAX8997_ADC_DESKDOCK:
+ case MAX8997_ADC_CARDOCK:
+ ret = max8997_muic_handle_dock(info, adc, true);
+ break;
+ case MAX8997_ADC_JIG_UART:
+ ret = max8997_muic_handle_jig_uart(info, true);
+ break;
+ case MAX8997_ADC_OPEN:
+ ret = max8997_muic_handle_adc_detach(info);
+ break;
+ default:
+ break;
+ }
+
+ info->pre_adc = adc;
+
+ return ret;
+}
+
+static int max8997_muic_handle_charger_type(struct max8997_muic_info *info,
+ enum max8997_muic_charger_type charger_type)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ u8 adc;
+ int ret;
+
+ ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ goto out;
+ }
+
+ switch (charger_type) {
+ case MAX8997_CHARGER_TYPE_NONE:
+ if (mdata->charger_callback)
+ mdata->charger_callback(false, charger_type);
+ if (info->pre_charger_type == MAX8997_CHARGER_TYPE_USB) {
+ max8997_muic_handle_usb(info,
+ MAX8997_USB_DEVICE, false);
+ }
+ break;
+ case MAX8997_CHARGER_TYPE_USB:
+ if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) {
+ max8997_muic_handle_usb(info,
+ MAX8997_USB_DEVICE, true);
+ }
+ if (mdata->charger_callback)
+ mdata->charger_callback(true, charger_type);
+ break;
+ case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
+ case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
+ case MAX8997_CHARGER_TYPE_500MA:
+ case MAX8997_CHARGER_TYPE_1A:
+ if (mdata->charger_callback)
+ mdata->charger_callback(true, charger_type);
+ break;
+ default:
+ break;
+ }
+
+ info->pre_charger_type = charger_type;
+out:
+ return ret;
+}
+
+static void max8997_muic_irq_work(struct work_struct *work)
+{
+ struct max8997_muic_info *info = container_of(work,
+ struct max8997_muic_info, irq_work);
+ struct max8997_platform_data *pdata =
+ dev_get_platdata(info->iodev->dev);
+ char env_name_str[30], env_state_str[15];
+ char *envp[] = { env_name_str, env_state_str, NULL };
+ u8 status[3];
+ u8 adc, adc_low, adc_err;
+ u8 vb_volt, db_chg, dcd_tmr, cdr, chg_type, ovp;
+
+ int irq_type = info->irq - pdata->irq_base;
+ int ret;
+
+ mutex_lock(&info->mutex);
+
+ ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
+ 3, status);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ mutex_unlock(&info->mutex);
+ return;
+ }
+
+ dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__,
+ status[0], status[1]);
+
+ switch (irq_type) {
+ case MAX8997_MUICIRQ_ADCError:
+ adc_err = status[0] & STATUS1_ADCERR_MASK;
+ adc_err >>= STATUS1_ADCERR_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "ADC_Error");
+ sprintf(env_state_str, "STATE=%d", adc_err);
+ break;
+ case MAX8997_MUICIRQ_ADCLow:
+ adc_low = status[0] & STATUS1_ADCLOW_MASK;
+ adc_low >>= STATUS1_ADCLOW_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "ADC_Low");
+ sprintf(env_state_str, "STATE=%d", adc_low);
+ break;
+ case MAX8997_MUICIRQ_ADC:
+ adc = status[0] & STATUS1_ADC_MASK;
+ adc >>= STATUS1_ADC_SHIFT;
+
+ max8997_muic_handle_adc(info, adc);
+
+ sprintf(env_name_str, "IRQ=%s", "ADC");
+ sprintf(env_state_str, "STATE=%d", adc);
+ break;
+ case MAX8997_MUICIRQ_VBVolt:
+ vb_volt = status[1] & STATUS2_VBVOLT_MASK;
+ vb_volt >>= STATUS2_VBVOLT_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "VB_Volt");
+ sprintf(env_state_str, "STATE=%d", vb_volt);
+ break;
+ case MAX8997_MUICIRQ_DBChg:
+ db_chg = status[1] & STATUS2_DBCHG_MASK;
+ db_chg >>= STATUS2_DBCHG_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "DB_CHARGER");
+ sprintf(env_state_str, "STATE=%d", db_chg);
+ break;
+ case MAX8997_MUICIRQ_DCDTmr:
+ dcd_tmr = status[1] & STATUS2_DCDTMR_MASK;
+ dcd_tmr >>= STATUS2_DCDTMR_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "DCD_TIMER");
+ sprintf(env_state_str, "STATE=%d", dcd_tmr);
+ break;
+ case MAX8997_MUICIRQ_ChgDetRun:
+ cdr = status[1] & STATUS2_CHGDETRUN_MASK;
+ cdr >>= STATUS2_CHGDETRUN_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "CHG_DET_RUN");
+ sprintf(env_state_str, "STATE=%d", cdr);
+ break;
+ case MAX8997_MUICIRQ_ChgTyp:
+ chg_type = status[1] & STATUS2_CHGTYP_MASK;
+ chg_type >>= STATUS2_CHGTYP_SHIFT;
+
+ max8997_muic_handle_charger_type(info, chg_type);
+
+ sprintf(env_name_str, "IRQ=%s", "CHARGER_TYPE");
+ sprintf(env_state_str, "STATE=%d", chg_type);
+ break;
+ case MAX8997_MUICIRQ_OVP:
+ ovp = status[2] & STATUS3_OVP_MASK;
+ ovp >>= STATUS3_OVP_SHIFT;
+ sprintf(env_name_str, "IRQ=%s", "OVER-VOLTAGE");
+ sprintf(env_state_str, "STATE=%d", ovp);
+ break;
+ default:
+ break;
+ }
+
+ kobject_uevent_env(&info->dev->kobj, KOBJ_CHANGE, envp);
+
+ mutex_unlock(&info->mutex);
+
+ return;
+}
+
+static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
+{
+ struct max8997_muic_info *info = data;
+
+ dev_dbg(info->dev, "irq:%d\n", irq);
+ info->irq = irq;
+
+ schedule_work(&info->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static void max8997_muic_detect_dev(struct max8997_muic_info *info)
+{
+ int ret;
+ u8 status[2], adc, chg_type;
+
+ ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
+ 2, status);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ return;
+ }
+
+ dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n",
+ status[0], status[1]);
+
+ adc = status[0] & STATUS1_ADC_MASK;
+ adc >>= STATUS1_ADC_SHIFT;
+
+ chg_type = status[1] & STATUS2_CHGTYP_MASK;
+ chg_type >>= STATUS2_CHGTYP_SHIFT;
+
+ max8997_muic_handle_adc(info, adc);
+ max8997_muic_handle_charger_type(info, chg_type);
+}
+
+static ssize_t max8997_muic_show_manualsw(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max8997_muic_info *info = dev_get_drvdata(dev);
+ int ret;
+ u8 value, manual_switch;
+
+ ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, &value);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ return sprintf(buf, "UNKNOWN\n");
+ }
+
+ manual_switch = value & (COMN1SW_MASK | COMP2SW_MASK);
+
+ switch (manual_switch) {
+ case MAX8997_SW_USB:
+ return sprintf(buf, "USB\n");
+ case MAX8997_SW_AUDIO:
+ return sprintf(buf, "AUDIO\n");
+ case MAX8997_SW_UART:
+ return sprintf(buf, "UART\n");
+ default:
+ return sprintf(buf, "OPEN\n");
+ }
+}
+
+static ssize_t max8997_muic_store_manualsw(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct max8997_muic_info *info = dev_get_drvdata(dev);
+ int ret;
+ u8 manual_switch;
+
+ if (!strncmp(buf, "USB", 3)) {
+ manual_switch = MAX8997_SW_USB;
+ } else if (!strncmp(buf, "AUDIO", 5)) {
+ manual_switch = MAX8997_SW_AUDIO;
+ } else if (!strncmp(buf, "UART", 4)) {
+ manual_switch = MAX8997_SW_UART;
+ } else if (!strncmp(buf, "OPEN", 4)) {
+ manual_switch = MAX8997_SW_OPEN;
+ } else {
+ dev_err(info->dev, "invalid parameter\n");
+ goto out;
+ }
+
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ manual_switch, SW_MASK);
+ if (ret)
+ dev_err(info->dev, "failed to update muic register\n");
+out:
+ return count;
+}
+
+static DEVICE_ATTR(switch, S_IRUGO | S_IWUSR,
+ max8997_muic_show_manualsw, max8997_muic_store_manualsw);
+
+static struct attribute *max8997_muic_attributes[] = {
+ &dev_attr_switch.attr,
+ NULL
+};
+
+static const struct attribute_group max8997_muic_group = {
+ .attrs = max8997_muic_attributes,
+};
+
+static void max8997_initialize_device(struct max8997_muic_info *info)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int i;
+
+ for (i = 0; i < mdata->num_init_data; i++) {
+ max8997_write_reg(info->muic, mdata->init_data[i].addr,
+ mdata->init_data[i].data);
+ }
+}
+
+static int __devinit max8997_muic_probe(struct platform_device *pdev)
+{
+ struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+ struct max8997_muic_info *info;
+ int ret, i;
+
+ info = kzalloc(sizeof(struct max8997_muic_info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ ret = -ENOMEM;
+ goto err_kfree;
+ }
+
+ if (!pdata->muic_pdata) {
+ dev_err(&pdev->dev, "failed to get platform_data\n");
+ ret = -EINVAL;
+ goto err_pdata;
+ }
+ info->muic_pdata = pdata->muic_pdata;
+
+ info->dev = &pdev->dev;
+ info->iodev = iodev;
+ info->muic = iodev->muic;
+
+ platform_set_drvdata(pdev, info);
+ mutex_init(&info->mutex);
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &max8997_muic_group);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed to create max8997 muic attribute group\n");
+ goto err_sysfs;
+ }
+
+ INIT_WORK(&info->irq_work, max8997_muic_irq_work);
+
+ for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
+ struct max8997_muic_irq *muic_irq = &muic_irqs[i];
+
+ ret = request_threaded_irq(pdata->irq_base + muic_irq->irq,
+ NULL, max8997_muic_irq_handler,
+ 0, muic_irq->name,
+ info);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d,"
+ " error :%d)\n",
+ muic_irq->irq, ret);
+
+ for (i = i - 1; i >= 0; i--)
+ free_irq(muic_irq->irq, info);
+
+ goto err_irq;
+ }
+ }
+
+ /* Initialize registers according to platform data */
+ max8997_initialize_device(info);
+
+ /* Initial device detection */
+ max8997_muic_detect_dev(info);
+
+ return ret;
+
+err_irq:
+ sysfs_remove_group(&pdev->dev.kobj, &max8997_muic_group);
+err_sysfs:
+err_pdata:
+ kfree(info);
+err_kfree:
+ return ret;
+}
+
+static int __devexit max8997_muic_remove(struct platform_device *pdev)
+{
+ struct max8997_muic_info *info = platform_get_drvdata(pdev);
+ struct max8997_platform_data *pdata =
+ dev_get_platdata(info->iodev->dev);
+ int i;
+
+ sysfs_remove_group(&pdev->dev.kobj, &max8997_muic_group);
+
+ for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
+ free_irq(pdata->irq_base + muic_irqs[i].irq, info);
+
+ kfree(info);
+
+ return 0;
+}
+
+static struct platform_driver max8997_muic_driver = {
+ .driver = {
+ .name = "max8997-muic",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8997_muic_probe,
+ .remove = __devexit_p(max8997_muic_remove),
+};
+
+static int __init max8997_muic_init(void)
+{
+ return platform_driver_register(&max8997_muic_driver);
+}
+module_init(max8997_muic_init);
+
+static void __exit max8997_muic_exit(void)
+{
+ platform_driver_unregister(&max8997_muic_driver);
+}
+module_exit(max8997_muic_exit);
+
+MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver");
+MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+MODULE_LICENSE("GPL");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-11-24 9:12 ` [PATCH 2/2] misc: add driver support for MAX8997 MUIC Donggeun Kim
@ 2011-11-28 23:48 ` Andrew Morton
2011-11-29 0:02 ` Kyungmin Park
2011-11-29 9:59 ` Samuel Ortiz
2011-12-12 17:08 ` Samuel Ortiz
1 sibling, 2 replies; 10+ messages in thread
From: Andrew Morton @ 2011-11-28 23:48 UTC (permalink / raw)
To: Donggeun Kim
Cc: linux-kernel, sameo, broonie, gregkh, kyungmin.park, myungjoo.ham
On Thu, 24 Nov 2011 18:12:18 +0900
Donggeun Kim <dg77.kim@samsung.com> wrote:
> The MUIC function in MAX8997 device can be used as
> a USB port detector and switch.
> This patch supports the MUIC feature of MAX8997.
>
> Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Samuel, can you please merge this if/when it's ready?
>
> ...
>
> +static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
> +{
> + struct max8997_muic_info *info = data;
> +
> + dev_dbg(info->dev, "irq:%d\n", irq);
> + info->irq = irq;
> +
> + schedule_work(&info->irq_work);
> +
> + return IRQ_HANDLED;
> +}
The code does schedule_work() but I see no flush_work(). Is it
possible for the work to still be pending after device shutdown, or
even after rmmod?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-11-28 23:48 ` Andrew Morton
@ 2011-11-29 0:02 ` Kyungmin Park
2011-11-29 9:59 ` Samuel Ortiz
1 sibling, 0 replies; 10+ messages in thread
From: Kyungmin Park @ 2011-11-29 0:02 UTC (permalink / raw)
To: Andrew Morton
Cc: Donggeun Kim, linux-kernel, sameo, broonie, gregkh, myungjoo.ham
On 11/29/11, Andrew Morton <akpm@linux-foundation.org> wrote:
> On Thu, 24 Nov 2011 18:12:18 +0900
> Donggeun Kim <dg77.kim@samsung.com> wrote:
>
>> The MUIC function in MAX8997 device can be used as
>> a USB port detector and switch.
>> This patch supports the MUIC feature of MAX8997.
>>
>> Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
>> Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
>> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>
> Samuel, can you please merge this if/when it's ready?
Thank you!
FYI: Now we proposed the new subsystem to handle the external
connector, "multistate switch'.
and this drivers is the candidate one for this subsystem.
Previous time, we sent the fsa9480, micro USB switch. this driver is
also covered at multistate switch framework.
Thank you,
Kyungmin Park
>
>>
>> ...
>>
>> +static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
>> +{
>> + struct max8997_muic_info *info = data;
>> +
>> + dev_dbg(info->dev, "irq:%d\n", irq);
>> + info->irq = irq;
>> +
>> + schedule_work(&info->irq_work);
>> +
>> + return IRQ_HANDLED;
>> +}
>
> The code does schedule_work() but I see no flush_work(). Is it
> possible for the work to still be pending after device shutdown, or
> even after rmmod?
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-11-28 23:48 ` Andrew Morton
2011-11-29 0:02 ` Kyungmin Park
@ 2011-11-29 9:59 ` Samuel Ortiz
1 sibling, 0 replies; 10+ messages in thread
From: Samuel Ortiz @ 2011-11-29 9:59 UTC (permalink / raw)
To: Andrew Morton
Cc: Donggeun Kim, linux-kernel, broonie, gregkh, kyungmin.park,
myungjoo.ham
Hi Andrew,
On Mon, Nov 28, 2011 at 03:48:01PM -0800, Andrew Morton wrote:
> On Thu, 24 Nov 2011 18:12:18 +0900
> Donggeun Kim <dg77.kim@samsung.com> wrote:
>
> > The MUIC function in MAX8997 device can be used as
> > a USB port detector and switch.
> > This patch supports the MUIC feature of MAX8997.
> >
> > Signed-off-by: Donggeun Kim <dg77.kim@samsung.com>
> > Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
>
> Samuel, can you please merge this if/when it's ready?
I will take it once I review it, yes.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-11-24 9:12 ` [PATCH 2/2] misc: add driver support for MAX8997 MUIC Donggeun Kim
2011-11-28 23:48 ` Andrew Morton
@ 2011-12-12 17:08 ` Samuel Ortiz
2011-12-14 16:35 ` Arnd Bergmann
1 sibling, 1 reply; 10+ messages in thread
From: Samuel Ortiz @ 2011-12-12 17:08 UTC (permalink / raw)
To: Donggeun Kim
Cc: linux-kernel, broonie, gregkh, akpm, kyungmin.park, myungjoo.ham,
Arnd Bergmann
Hi Kim,
On Thu, Nov 24, 2011 at 06:12:18PM +0900, Donggeun Kim wrote:
> The MUIC function in MAX8997 device can be used as
> a USB port detector and switch.
> This patch supports the MUIC feature of MAX8997.
I'm queueing this one to my for-next branch as it depends on your previous MFD
patch.
I'm also cc'ing Arnd in case he has some objections.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-12-12 17:08 ` Samuel Ortiz
@ 2011-12-14 16:35 ` Arnd Bergmann
0 siblings, 0 replies; 10+ messages in thread
From: Arnd Bergmann @ 2011-12-14 16:35 UTC (permalink / raw)
To: Samuel Ortiz
Cc: Donggeun Kim, linux-kernel, broonie, gregkh, akpm, kyungmin.park,
myungjoo.ham
On Monday 12 December 2011, Samuel Ortiz wrote:
> On Thu, Nov 24, 2011 at 06:12:18PM +0900, Donggeun Kim wrote:
> > The MUIC function in MAX8997 device can be used as
> > a USB port detector and switch.
> > This patch supports the MUIC feature of MAX8997.
>
> I'm queueing this one to my for-next branch as it depends on your previous MFD
> patch.
> I'm also cc'ing Arnd in case he has some objections.
Thanks for the notification!
First of all, every new user space interface including new sysfs files
and uevent messages needs documentation in the Documentation/ABI
directory.
The part that is not clear to me is how this new driver fits in
with the first fsa9480 driver and the currently discussed extcon
subsystem, apparently all written by the same team at Samsung.
Is this misc driver still useful when the extcon framework gets
merged?
I very much believe that we should avoid introducing user interfaces
in a driver specific way when we have multiple pieces of hardware
that try to do the same thing. The extcon subsystem seems to handle
this correctly on the high-level (I have not done a detailed
review yet but I trust that it will be ok), so I don't understand
why we want another driver for the MAX8997 MUIC.
Arnd
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
@ 2011-12-15 0:32 MyungJoo Ham
2011-12-15 15:34 ` Arnd Bergmann
0 siblings, 1 reply; 10+ messages in thread
From: MyungJoo Ham @ 2011-12-15 0:32 UTC (permalink / raw)
To: Arnd Bergmann, Samuel Ortiz
Cc: 김동근, linux-kernel@vger.kernel.org,
broonie@opensource.wolfsonmicro.com, gregkh@suse.de,
akpm@linux-foundation.org, 박경민
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=euc-kr, Size: 2239 bytes --]
> On Monday 12 December 2011, Samuel Ortiz wrote:
> > On Thu, Nov 24, 2011 at 06:12:18PM +0900, Donggeun Kim wrote:
> > > The MUIC function in MAX8997 device can be used as
> > > a USB port detector and switch.
> > > This patch supports the MUIC feature of MAX8997.
> >
> > I'm queueing this one to my for-next branch as it depends on your previous MFD
> > patch.
> > I'm also cc'ing Arnd in case he has some objections.
>
> Thanks for the notification!
>
> First of all, every new user space interface including new sysfs files
> and uevent messages needs documentation in the Documentation/ABI
> directory.
>
> The part that is not clear to me is how this new driver fits in
> with the first fsa9480 driver and the currently discussed extcon
> subsystem, apparently all written by the same team at Samsung.
> Is this misc driver still useful when the extcon framework gets
> merged?
When extcom gets merged, this driver should be updated. It looks like allowing the interrupt handler to update extcon state would be enough. Bascially, this is all this driver is required for extcon to work. (and the prvious author of extcon--"extended" switch class at that time--was the author of this patch.)
Anyway, this patch has just told me that I'll need to add more sysfs entries for extcon to show the list of cable names and/or to show the status for each of them, soon or later.
>
> I very much believe that we should avoid introducing user interfaces
> in a driver specific way when we have multiple pieces of hardware
> that try to do the same thing. The extcon subsystem seems to handle
> this correctly on the high-level (I have not done a detailed
> review yet but I trust that it will be ok), so I don't understand
> why we want another driver for the MAX8997 MUIC.
This sysfs entry is a bit confusing to me (that userspace may update this CONTROL register). I'll consult Donggeun when he arrives and will write again about this one. If it is not writable, this is supported by extcon framework, so this sysfs entry will disappear adapting extcon.
Cheers!
MyungJoo
ÿôèº{.nÇ+·®+%Ëÿ±éݶ\x17¥wÿº{.nÇ+·¥{±þG«éÿ{ayº\x1dÊÚë,j\a¢f£¢·hïêÿêçz_è®\x03(éÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?¨èÚ&£ø§~á¶iOæ¬z·vØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?I¥
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-12-15 0:32 Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC MyungJoo Ham
@ 2011-12-15 15:34 ` Arnd Bergmann
2011-12-15 17:25 ` Samuel Ortiz
0 siblings, 1 reply; 10+ messages in thread
From: Arnd Bergmann @ 2011-12-15 15:34 UTC (permalink / raw)
To: myungjoo.ham
Cc: Samuel Ortiz, 김동근,
linux-kernel@vger.kernel.org, broonie@opensource.wolfsonmicro.com,
gregkh@suse.de, akpm@linux-foundation.org,
박경민
On Thursday 15 December 2011, MyungJoo Ham wrote:
> Arnd Bergmann wrote:
> > On Monday 12 December 2011, Samuel Ortiz wrote:
> > The part that is not clear to me is how this new driver fits in
> > with the first fsa9480 driver and the currently discussed extcon
> > subsystem, apparently all written by the same team at Samsung.
> > Is this misc driver still useful when the extcon framework gets
> > merged?
>
> When extcom gets merged, this driver should be updated. It looks like allowing
> the interrupt handler to update extcon state would be enough. Bascially, this
> is all this driver is required for extcon to work. (and the prvious author of
> extcon--"extended" switch class at that time--was the author of this patch.)
>
> Anyway, this patch has just told me that I'll need to add more sysfs entries
> for extcon to show the list of cable names and/or to show the status for each
> of them, soon or later.
I think it would be better not to merge this driver until the user interface
in the extcon framework has been finalized. I don't mind the driver, but I
want to prevent user interfaces from appearing in the kernel that we
intend to change anyway.
How about dropping the driver from the mfd tree, and adding it into the
extcon series for the next posting?
Arnd
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-12-15 15:34 ` Arnd Bergmann
@ 2011-12-15 17:25 ` Samuel Ortiz
0 siblings, 0 replies; 10+ messages in thread
From: Samuel Ortiz @ 2011-12-15 17:25 UTC (permalink / raw)
To: Arnd Bergmann
Cc: myungjoo.ham, 김동근,
linux-kernel@vger.kernel.org, broonie@opensource.wolfsonmicro.com,
gregkh@suse.de, akpm@linux-foundation.org,
박경민
Hi Arnd,
On Thu, Dec 15, 2011 at 03:34:01PM +0000, Arnd Bergmann wrote:
> On Thursday 15 December 2011, MyungJoo Ham wrote:
> > Arnd Bergmann wrote:
> > > On Monday 12 December 2011, Samuel Ortiz wrote:
> > > The part that is not clear to me is how this new driver fits in
> > > with the first fsa9480 driver and the currently discussed extcon
> > > subsystem, apparently all written by the same team at Samsung.
> > > Is this misc driver still useful when the extcon framework gets
> > > merged?
> >
> > When extcom gets merged, this driver should be updated. It looks like allowing
> > the interrupt handler to update extcon state would be enough. Bascially, this
> > is all this driver is required for extcon to work. (and the prvious author of
> > extcon--"extended" switch class at that time--was the author of this patch.)
> >
> > Anyway, this patch has just told me that I'll need to add more sysfs entries
> > for extcon to show the list of cable names and/or to show the status for each
> > of them, soon or later.
>
> I think it would be better not to merge this driver until the user interface
> in the extcon framework has been finalized. I don't mind the driver, but I
> want to prevent user interfaces from appearing in the kernel that we
> intend to change anyway.
>
> How about dropping the driver from the mfd tree, and adding it into the
> extcon series for the next posting?
Sounds good to me, I'll drop it.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC
2011-12-16 5:13 함명주
@ 2011-12-16 13:58 ` Arnd Bergmann
0 siblings, 0 replies; 10+ messages in thread
From: Arnd Bergmann @ 2011-12-16 13:58 UTC (permalink / raw)
To: myungjoo.ham
Cc: Samuel Ortiz, 김동근,
linux-kernel@vger.kernel.org, broonie@opensource.wolfsonmicro.com,
gregkh@suse.de, akpm@linux-foundation.org,
박경민
On Friday 16 December 2011, 함명주 wrote:
> We can send the patch (with extcon support) later anyway if it's going to be dropped for now.
>
> And, this MAX8997-MUIC will be the example driver for extcon located at /drivers/extcon/.
>
Ok, sounds good.
Arnd
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2011-12-16 13:58 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-15 0:32 Re: [PATCH 2/2] misc: add driver support for MAX8997 MUIC MyungJoo Ham
2011-12-15 15:34 ` Arnd Bergmann
2011-12-15 17:25 ` Samuel Ortiz
-- strict thread matches above, loose matches on Subject: below --
2011-12-16 5:13 함명주
2011-12-16 13:58 ` Arnd Bergmann
2011-11-24 9:12 [PATCH 1/2] MFD: MAX8997: add platform data for MAX8997 MUIC driver Donggeun Kim
2011-11-24 9:12 ` [PATCH 2/2] misc: add driver support for MAX8997 MUIC Donggeun Kim
2011-11-28 23:48 ` Andrew Morton
2011-11-29 0:02 ` Kyungmin Park
2011-11-29 9:59 ` Samuel Ortiz
2011-12-12 17:08 ` Samuel Ortiz
2011-12-14 16:35 ` Arnd Bergmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox