mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 16:53:54 +08:00
Update extcon for 4.5
Detailed description for patchset: 1. Add new MAX3355 extcon driver - Maxim Integrated MAX3355E chip integrates a charge pump and comparator to enable a system with an integrated USB OTG dual-role transceiver to function as an USB OTG dual-role device. 2. Update the extcon-arizona driver for jack detection - Add the device binding for the jack detection and add the documentation of extcon-arizona.c. 3. Fix the minor issue of extcon driver - Add IRQF_ONESHOT to interrupt flags of extcon-rt8973. - Fix the return value regmap_irq_get_virq() of extcon-max(14577|77693|77843).c driver by using script[1]. [1] http://permalink.gmane.org/gmane.linux.kernel/2046107 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWez8EAAoJEJzN3yze689THRIQANQE43HnltSAF2rh9b9r92/v 1Eb2TeeJPD5NuYUdx7NkkHy0JpIPs1nlT/MS26Ow4p2OfQVOBa/pJQvJcIV+ovA/ bGeEzohfCrBYFA3moyKtad57b/9moaBjvK1XJmjQ/abNvg1C0fZC+gWBxX0YoopQ I+epOlkVGgT1gEYwOSdc2Rlj10gCMjogkDvi8enufJ0IzjXxEM9DP0XLCzR8tNnX +zuWNrAbA0PUY2uKLlExe9EyxX+/7JlkpCgBVo2FNEjowh1u4vLc4+dWQjCbYp1F d6z04lhsWW1ohHaW3BsECBp5+XpwNUUjOASlQgP+UjP6oA/raKeSc+TBbaF5CQ4f sf4ip8t2FvA9E5Q08lp/vyxJMzrZe+uWYM2qCOhC+gXHpS8Oq2coKEoR7aydr3KK M0RifubLwC9VKmmi4Xh1vlUi8F48mClXPdSbMY4+etLRUxOSjM67aUodwnygm1tU dYhR02ayFfkQNhFzlqHY9nFo50Ql0r7nxbGRXgE8Sm7aI/7H/0/LO2umBTgIaBu4 CINEP/6sE4UOOpgO1Gdw9/xTNebCfm2I6MFBR6hIQndJvtTERtCop+tDm38HOicZ 4zYXG82kbil7CKiGav0RIHj97dkXrxeojnhCE0IeeJk9Jw3OL0nEABl2PaiDxkLy VshIB1VeEC5t8m+KNOEX =t21V -----END PGP SIGNATURE----- Merge tag 'extcon-next-for-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon into char-misc-next Chanwoo writes: Update extcon for 4.5 Detailed description for patchset: 1. Add new MAX3355 extcon driver - Maxim Integrated MAX3355E chip integrates a charge pump and comparator to enable a system with an integrated USB OTG dual-role transceiver to function as an USB OTG dual-role device. 2. Update the extcon-arizona driver for jack detection - Add the device binding for the jack detection and add the documentation of extcon-arizona.c. 3. Fix the minor issue of extcon driver - Add IRQF_ONESHOT to interrupt flags of extcon-rt8973. - Fix the return value regmap_irq_get_virq() of extcon-max(14577|77693|77843).c driver by using script[1]. [1] http://permalink.gmane.org/gmane.linux.kernel/2046107
This commit is contained in:
commit
d7a26beb6f
@ -13,3 +13,63 @@ Optional properties:
|
||||
ARIZONA_ACCDET_MODE_HPR or 2 - Headphone detect mode is set to HPDETR
|
||||
If this node is not mentioned or if the value is unknown, then
|
||||
headphone detection mode is set to HPDETL.
|
||||
|
||||
- wlf,use-jd2 : Use the additional JD input along with JD1 for dual pin jack
|
||||
detection.
|
||||
- wlf,use-jd2-nopull : Internal pull on JD2 is disabled when used for
|
||||
jack detection.
|
||||
- wlf,jd-invert : Invert the polarity of the jack detection switch
|
||||
|
||||
- wlf,micd-software-compare : Use a software comparison to determine mic
|
||||
presence
|
||||
- wlf,micd-detect-debounce : Additional software microphone detection
|
||||
debounce specified in milliseconds.
|
||||
- wlf,micd-pol-gpio : GPIO specifier for the GPIO controlling the headset
|
||||
polarity if one exists.
|
||||
- wlf,micd-bias-start-time : Time allowed for MICBIAS to startup prior to
|
||||
performing microphone detection, specified as per the ARIZONA_MICD_TIME_XXX
|
||||
defines.
|
||||
- wlf,micd-rate : Delay between successive microphone detection measurements,
|
||||
specified as per the ARIZONA_MICD_TIME_XXX defines.
|
||||
- wlf,micd-dbtime : Microphone detection hardware debounces specified as the
|
||||
number of measurements to take, valid values being 2 and 4.
|
||||
- wlf,micd-timeout-ms : Timeout for microphone detection, specified in
|
||||
milliseconds.
|
||||
- wlf,micd-force-micbias : Force MICBIAS continuously on during microphone
|
||||
detection.
|
||||
- wlf,micd-configs : Headset polarity configurations (generally used for
|
||||
detection of CTIA / OMTP headsets), the field can be of variable length
|
||||
but should always be a multiple of 3 cells long, each three cell group
|
||||
represents one polarity configuration.
|
||||
The first cell defines the accessory detection pin, zero will use MICDET1
|
||||
and all other values will use MICDET2.
|
||||
The second cell represents the MICBIAS to be used.
|
||||
The third cell represents the value of the micd-pol-gpio pin.
|
||||
|
||||
- wlf,gpsw : Settings for the general purpose switch
|
||||
|
||||
Example:
|
||||
|
||||
codec: wm8280@0 {
|
||||
compatible = "wlf,wm8280";
|
||||
reg = <0>;
|
||||
...
|
||||
|
||||
wlf,use-jd2;
|
||||
wlf,use-jd2-nopull;
|
||||
wlf,jd-invert;
|
||||
|
||||
wlf,micd-software-compare;
|
||||
wlf,micd-detect-debounce = <0>;
|
||||
wlf,micd-pol-gpio = <&codec 2 0>;
|
||||
wlf,micd-rate = <ARIZONA_MICD_TIME_8MS>;
|
||||
wlf,micd-dbtime = <4>;
|
||||
wlf,micd-timeout-ms = <100>;
|
||||
wlf,micd-force-micbias;
|
||||
wlf,micd-configs = <
|
||||
0 1 0 /* MICDET1 MICBIAS1 GPIO=low */
|
||||
1 2 1 /* MICDET2 MICBIAS2 GPIO=high */
|
||||
>;
|
||||
|
||||
wlf,gpsw = <0>;
|
||||
};
|
||||
|
21
Documentation/devicetree/bindings/extcon/extcon-max3355.txt
Normal file
21
Documentation/devicetree/bindings/extcon/extcon-max3355.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Maxim Integrated MAX3355 USB OTG chip
|
||||
-------------------------------------
|
||||
|
||||
MAX3355 integrates a charge pump and comparators to enable a system with an
|
||||
integrated USB OTG dual-role transceiver to function as a USB OTG dual-role
|
||||
device.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "maxim,max3355";
|
||||
- maxim,shdn-gpios: should contain a phandle and GPIO specifier for the GPIO pin
|
||||
connected to the MAX3355's SHDN# pin;
|
||||
- id-gpios: should contain a phandle and GPIO specifier for the GPIO pin
|
||||
connected to the MAX3355's ID_OUT pin.
|
||||
|
||||
Example:
|
||||
|
||||
usb-otg {
|
||||
compatible = "maxim,max3355";
|
||||
maxim,shdn-gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
|
||||
id-gpios = <&gpio5 31 GPIO_ACTIVE_HIGH>;
|
||||
};
|
@ -52,6 +52,15 @@ config EXTCON_MAX14577
|
||||
Maxim MAX14577/77836. The MAX14577/77836 MUIC is a USB port accessory
|
||||
detector and switch.
|
||||
|
||||
config EXTCON_MAX3355
|
||||
tristate "Maxim MAX3355 USB OTG EXTCON Support"
|
||||
depends on GPIOLIB || COMPILE_TEST
|
||||
help
|
||||
If you say yes here you get support for the USB OTG role detection by
|
||||
MAX3355. The MAX3355 chip integrates a charge pump and comparators to
|
||||
enable a system with an integrated USB OTG dual-role transceiver to
|
||||
function as an USB OTG dual-role device.
|
||||
|
||||
config EXTCON_MAX77693
|
||||
tristate "Maxim MAX77693 EXTCON Support"
|
||||
depends on MFD_MAX77693 && INPUT
|
||||
|
@ -8,6 +8,7 @@ obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
|
||||
obj-$(CONFIG_EXTCON_AXP288) += extcon-axp288.o
|
||||
obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
|
||||
obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o
|
||||
obj-$(CONFIG_EXTCON_MAX3355) += extcon-max3355.o
|
||||
obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
|
||||
obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o
|
||||
obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o
|
||||
|
@ -1201,10 +1201,58 @@ static void arizona_micd_set_level(struct arizona *arizona, int index,
|
||||
regmap_update_bits(arizona->regmap, reg, mask, level);
|
||||
}
|
||||
|
||||
static int arizona_extcon_device_get_pdata(struct arizona *arizona)
|
||||
static int arizona_extcon_get_micd_configs(struct device *dev,
|
||||
struct arizona *arizona)
|
||||
{
|
||||
const char * const prop = "wlf,micd-configs";
|
||||
const int entries_per_config = 3;
|
||||
struct arizona_micd_config *micd_configs;
|
||||
int nconfs, ret;
|
||||
int i, j;
|
||||
u32 *vals;
|
||||
|
||||
nconfs = device_property_read_u32_array(arizona->dev, prop, NULL, 0);
|
||||
if (nconfs <= 0)
|
||||
return 0;
|
||||
|
||||
vals = kcalloc(nconfs, sizeof(u32), GFP_KERNEL);
|
||||
if (!vals)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = device_property_read_u32_array(arizona->dev, prop, vals, nconfs);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
nconfs /= entries_per_config;
|
||||
|
||||
micd_configs = devm_kzalloc(dev,
|
||||
nconfs * sizeof(struct arizona_micd_range),
|
||||
GFP_KERNEL);
|
||||
if (!micd_configs) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < nconfs; ++i) {
|
||||
micd_configs[i].src = vals[j++] ? ARIZONA_ACCDET_SRC : 0;
|
||||
micd_configs[i].bias = vals[j++];
|
||||
micd_configs[i].gpio = vals[j++];
|
||||
}
|
||||
|
||||
arizona->pdata.micd_configs = micd_configs;
|
||||
arizona->pdata.num_micd_configs = nconfs;
|
||||
|
||||
out:
|
||||
kfree(vals);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int arizona_extcon_device_get_pdata(struct device *dev,
|
||||
struct arizona *arizona)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
unsigned int val = ARIZONA_ACCDET_MODE_HPL;
|
||||
int ret;
|
||||
|
||||
device_property_read_u32(arizona->dev, "wlf,hpdet-channel", &val);
|
||||
switch (val) {
|
||||
@ -1230,12 +1278,29 @@ static int arizona_extcon_device_get_pdata(struct arizona *arizona)
|
||||
device_property_read_u32(arizona->dev, "wlf,micd-dbtime",
|
||||
&pdata->micd_dbtime);
|
||||
|
||||
device_property_read_u32(arizona->dev, "wlf,micd-timeout",
|
||||
device_property_read_u32(arizona->dev, "wlf,micd-timeout-ms",
|
||||
&pdata->micd_timeout);
|
||||
|
||||
pdata->micd_force_micbias = device_property_read_bool(arizona->dev,
|
||||
"wlf,micd-force-micbias");
|
||||
|
||||
pdata->micd_software_compare = device_property_read_bool(arizona->dev,
|
||||
"wlf,micd-software-compare");
|
||||
|
||||
pdata->jd_invert = device_property_read_bool(arizona->dev,
|
||||
"wlf,jd-invert");
|
||||
|
||||
device_property_read_u32(arizona->dev, "wlf,gpsw", &pdata->gpsw);
|
||||
|
||||
pdata->jd_gpio5 = device_property_read_bool(arizona->dev,
|
||||
"wlf,use-jd2");
|
||||
pdata->jd_gpio5_nopull = device_property_read_bool(arizona->dev,
|
||||
"wlf,use-jd2-nopull");
|
||||
|
||||
ret = arizona_extcon_get_micd_configs(dev, arizona);
|
||||
if (ret < 0)
|
||||
dev_err(arizona->dev, "Failed to read micd configs: %d\n", ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1257,7 +1322,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!dev_get_platdata(arizona->dev))
|
||||
arizona_extcon_device_get_pdata(arizona);
|
||||
arizona_extcon_device_get_pdata(&pdev->dev, arizona);
|
||||
|
||||
info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
|
||||
if (IS_ERR(info->micvdd)) {
|
||||
|
@ -692,7 +692,7 @@ static int max14577_muic_probe(struct platform_device *pdev)
|
||||
/* Support irq domain for max14577 MUIC device */
|
||||
for (i = 0; i < info->muic_irqs_num; i++) {
|
||||
struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
|
||||
unsigned int virq = 0;
|
||||
int virq = 0;
|
||||
|
||||
virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
|
||||
if (virq <= 0)
|
||||
|
146
drivers/extcon/extcon-max3355.c
Normal file
146
drivers/extcon/extcon-max3355.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Maxim Integrated MAX3355 USB OTG chip extcon driver
|
||||
*
|
||||
* Copyright (C) 2014-2015 Cogent Embedded, Inc.
|
||||
* Author: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*/
|
||||
|
||||
#include <linux/extcon.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
struct max3355_data {
|
||||
struct extcon_dev *edev;
|
||||
struct gpio_desc *id_gpiod;
|
||||
struct gpio_desc *shdn_gpiod;
|
||||
};
|
||||
|
||||
static const unsigned int max3355_cable[] = {
|
||||
EXTCON_USB,
|
||||
EXTCON_USB_HOST,
|
||||
EXTCON_NONE,
|
||||
};
|
||||
|
||||
static irqreturn_t max3355_id_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct max3355_data *data = dev_id;
|
||||
int id = gpiod_get_value_cansleep(data->id_gpiod);
|
||||
|
||||
if (id) {
|
||||
/*
|
||||
* ID = 1 means USB HOST cable detached.
|
||||
* As we don't have event for USB peripheral cable attached,
|
||||
* we simulate USB peripheral attach here.
|
||||
*/
|
||||
extcon_set_cable_state_(data->edev, EXTCON_USB_HOST, false);
|
||||
extcon_set_cable_state_(data->edev, EXTCON_USB, true);
|
||||
} else {
|
||||
/*
|
||||
* ID = 0 means USB HOST cable attached.
|
||||
* As we don't have event for USB peripheral cable detached,
|
||||
* we simulate USB peripheral detach here.
|
||||
*/
|
||||
extcon_set_cable_state_(data->edev, EXTCON_USB, false);
|
||||
extcon_set_cable_state_(data->edev, EXTCON_USB_HOST, true);
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int max3355_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct max3355_data *data;
|
||||
struct gpio_desc *gpiod;
|
||||
int irq, err;
|
||||
|
||||
data = devm_kzalloc(&pdev->dev, sizeof(struct max3355_data),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
gpiod = devm_gpiod_get(&pdev->dev, "id", GPIOD_IN);
|
||||
if (IS_ERR(gpiod)) {
|
||||
dev_err(&pdev->dev, "failed to get ID_OUT GPIO\n");
|
||||
return PTR_ERR(gpiod);
|
||||
}
|
||||
data->id_gpiod = gpiod;
|
||||
|
||||
gpiod = devm_gpiod_get(&pdev->dev, "maxim,shdn", GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(gpiod)) {
|
||||
dev_err(&pdev->dev, "failed to get SHDN# GPIO\n");
|
||||
return PTR_ERR(gpiod);
|
||||
}
|
||||
data->shdn_gpiod = gpiod;
|
||||
|
||||
data->edev = devm_extcon_dev_allocate(&pdev->dev, max3355_cable);
|
||||
if (IS_ERR(data->edev)) {
|
||||
dev_err(&pdev->dev, "failed to allocate extcon device\n");
|
||||
return PTR_ERR(data->edev);
|
||||
}
|
||||
|
||||
err = devm_extcon_dev_register(&pdev->dev, data->edev);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to register extcon device\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
irq = gpiod_to_irq(data->id_gpiod);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to translate ID_OUT GPIO to IRQ\n");
|
||||
return irq;
|
||||
}
|
||||
|
||||
err = devm_request_threaded_irq(&pdev->dev, irq, NULL, max3355_id_irq,
|
||||
IRQF_ONESHOT | IRQF_NO_SUSPEND |
|
||||
IRQF_TRIGGER_RISING |
|
||||
IRQF_TRIGGER_FALLING,
|
||||
pdev->name, data);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to request ID_OUT IRQ\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, data);
|
||||
|
||||
/* Perform initial detection */
|
||||
max3355_id_irq(irq, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max3355_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct max3355_data *data = platform_get_drvdata(pdev);
|
||||
|
||||
gpiod_set_value_cansleep(data->shdn_gpiod, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id max3355_match_table[] = {
|
||||
{ .compatible = "maxim,max3355", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max3355_match_table);
|
||||
|
||||
static struct platform_driver max3355_driver = {
|
||||
.probe = max3355_probe,
|
||||
.remove = max3355_remove,
|
||||
.driver = {
|
||||
.name = "extcon-max3355",
|
||||
.of_match_table = max3355_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(max3355_driver);
|
||||
|
||||
MODULE_AUTHOR("Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>");
|
||||
MODULE_DESCRIPTION("Maxim MAX3355 extcon driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1127,11 +1127,11 @@ static int max77693_muic_probe(struct platform_device *pdev)
|
||||
/* Support irq domain for MAX77693 MUIC device */
|
||||
for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
|
||||
struct max77693_muic_irq *muic_irq = &muic_irqs[i];
|
||||
unsigned int virq = 0;
|
||||
int virq;
|
||||
|
||||
virq = regmap_irq_get_virq(max77693->irq_data_muic,
|
||||
muic_irq->irq);
|
||||
if (!virq)
|
||||
if (virq <= 0)
|
||||
return -EINVAL;
|
||||
muic_irq->virq = virq;
|
||||
|
||||
|
@ -811,7 +811,7 @@ static int max77843_muic_probe(struct platform_device *pdev)
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(max77843_muic_irqs); i++) {
|
||||
struct max77843_muic_irq *muic_irq = &max77843_muic_irqs[i];
|
||||
unsigned int virq = 0;
|
||||
int virq = 0;
|
||||
|
||||
virq = regmap_irq_get_virq(max77843->irq_data_muic,
|
||||
muic_irq->irq);
|
||||
|
@ -603,7 +603,7 @@ static int rt8973a_muic_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
ret = devm_request_threaded_irq(info->dev, virq, NULL,
|
||||
rt8973a_muic_irq_handler,
|
||||
IRQF_NO_SUSPEND,
|
||||
IRQF_NO_SUSPEND | IRQF_ONESHOT,
|
||||
muic_irq->name, info);
|
||||
if (ret) {
|
||||
dev_err(info->dev,
|
||||
|
Loading…
Reference in New Issue
Block a user