diff --git a/Documentation/devicetree/bindings/sound/wm8903.txt b/Documentation/devicetree/bindings/sound/wm8903.txt new file mode 100644 index 000000000000..f102cbc42694 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8903.txt @@ -0,0 +1,50 @@ +WM8903 audio CODEC + +This device supports I2C only. + +Required properties: + + - compatible : "wlf,wm8903" + + - reg : the I2C address of the device. + + - gpio-controller : Indicates this device is a GPIO controller. + + - #gpio-cells : Should be two. The first cell is the pin number and the + second cell is used to specify optional parameters (currently unused). + +Optional properties: + + - interrupts : The interrupt line the codec is connected to. + + - micdet-cfg : Default register value for R6 (Mic Bias). If absent, the + default is 0. + + - micdet-delay : The debounce delay for microphone detection in mS. If + absent, the default is 100. + + - gpio-cfg : A list of GPIO configuration register values. The list must + be 5 entries long. If absent, no configuration of these registers is + performed. If any entry has the value 0xffffffff, that GPIO's + configuration will not be modified. + +Example: + +codec: wm8903@1a { + compatible = "wlf,wm8903"; + reg = <0x1a>; + interrupts = < 347 >; + + gpio-controller; + #gpio-cells = <2>; + + micdet-cfg = <0>; + micdet-delay = <100>; + gpio-cfg = < + 0x0600 /* DMIC_LR, output */ + 0x0680 /* DMIC_DAT, input */ + 0x0000 /* GPIO, output, low */ + 0x0200 /* Interrupt, output */ + 0x01a0 /* BCLK, input, active high */ + >; +}; diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b4f2c906b2f3..adfbefaaab21 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -2070,6 +2070,49 @@ static int wm8903_set_pdata_irq_trigger(struct i2c_client *i2c, return 0; } +static int wm8903_set_pdata_from_of(struct i2c_client *i2c, + struct wm8903_platform_data *pdata) +{ + const struct device_node *np = i2c->dev.of_node; + u32 val32; + int i; + + if (of_property_read_u32(np, "micdet-cfg", &val32) >= 0) + pdata->micdet_cfg = val32; + + if (of_property_read_u32(np, "micdet-delay", &val32) >= 0) + pdata->micdet_delay = val32; + + if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_cfg, + ARRAY_SIZE(pdata->gpio_cfg)) >= 0) { + /* + * In device tree: 0 means "write 0", + * 0xffffffff means "don't touch". + * + * In platform data: 0 means "don't touch", + * 0x8000 means "write 0". + * + * Note: WM8903_GPIO_CONFIG_ZERO == 0x8000. + * + * Convert from DT to pdata representation here, + * so no other code needs to change. + */ + for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { + if (pdata->gpio_cfg[i] == 0) { + pdata->gpio_cfg[i] = WM8903_GPIO_CONFIG_ZERO; + } else if (pdata->gpio_cfg[i] == 0xffffffff) { + pdata->gpio_cfg[i] = 0; + } else if (pdata->gpio_cfg[i] > 0x7fff) { + dev_err(&i2c->dev, "Invalid gpio-cfg[%d] %x\n", + i, pdata->gpio_cfg[i]); + return -EINVAL; + } + } + } + + return 0; +} + static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { @@ -2111,6 +2154,12 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, if (ret != 0) return ret; } + + if (i2c->dev.of_node) { + ret = wm8903_set_pdata_from_of(i2c, wm8903->pdata); + if (ret != 0) + return ret; + } } ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);