- wlf,reset : GPIO specifier for the GPIO controlling /RESET
- wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
- - wlf,gpio-defaults : A list of GPIO configuration register values. Defines
- for the appropriate values can found in <dt-bindings/mfd/arizona.txt>. If
- absent, no configuration of these registers is performed. If any entry has
- a value that is out of range for a 16 bit register then the chip default
- will be used. If present exactly five values must be specified.
+
+ - wlf,micd-ranges : Microphone detection level and key configuration, this
+ field can be of variable length but should always be a multiple of 2 cells
+ long, each two cell group represents one button configuration
+ The first cell is the maximum impedance for this button in ohms
+ The second cell the key that should be reported to the input layer
+ - wlf,micd-configs : Headset polarity configurations, the field can be of
+ variable length but should always be a multiple of 3 cells long, each two
+ cell group represents one polarity configration
+ The first cell is the accessory detection source as per the ACCDET_SRC bits
+ in the ACCESSORY_DETECT_MODE_1 register
+ The second cell represents the MICBIAS to be used as per the MICD_BIAS_SRC
+ bits in the MIC_DETECT_1 register
+ The third cell represents the value of the micd-pol-gpio pin, a non-zero
+ value indicates this should be on
- wlf,inmode : A list of INn_MODE register values, where n is the number
of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
wlf,gpsw = <0x3>;
+ wlf,micd-ranges = <
+ 11 0x100
+ 28 0x101
+ 54 0x102
+ 100 0x103
+ 186 0x104
+ 430 0x105
+ >;
+ wlf,micd-configs = <
+ 0x1 1 0
+ 0x0 2 1
+ >;
+
wlf,gpio-defaults = <
ARIZONA_GP_FN_TXLRCLK
ARIZONA_GP_DEFAULT
}
EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
+static int arizona_of_get_u32_num_groups(struct arizona *arizona,
+ const char *prop,
+ int group_size)
+{
+ int len_prop;
+ int num_groups;
+
+ if (!of_get_property(arizona->dev->of_node, prop, &len_prop))
+ return -EINVAL;
+
+ num_groups = len_prop / (group_size * sizeof(u32));
+
+ if (num_groups * group_size * sizeof(u32) != len_prop) {
+ dev_err(arizona->dev,
+ "DT property %s is malformed: %d\n",
+ prop, -EOVERFLOW);
+ return -EOVERFLOW;
+ }
+
+ return num_groups;
+}
+
+static int arizona_of_get_micd_ranges(struct arizona *arizona,
+ const char *prop)
+{
+ int nranges;
+ int i, j;
+ int ret = 0;
+ u32 value;
+ struct arizona_micd_range *micd_ranges;
+
+ nranges = arizona_of_get_u32_num_groups(arizona, prop, 2);
+ if (nranges < 0)
+ return nranges;
+
+ micd_ranges = devm_kzalloc(arizona->dev,
+ nranges * sizeof(struct arizona_micd_range),
+ GFP_KERNEL);
+
+ for (i = 0, j = 0; i < nranges; ++i) {
+ ret = of_property_read_u32_index(arizona->dev->of_node,
+ prop, j++, &value);
+ if (ret < 0)
+ goto error;
+ micd_ranges[i].max = value;
+
+ ret = of_property_read_u32_index(arizona->dev->of_node,
+ prop, j++, &value);
+ if (ret < 0)
+ goto error;
+ micd_ranges[i].key = value;
+ }
+
+ arizona->pdata.micd_ranges = micd_ranges;
+ arizona->pdata.num_micd_ranges = nranges;
+
+ return ret;
+
+error:
+ devm_kfree(arizona->dev, micd_ranges);
+ dev_err(arizona->dev, "DT property %s is malformed: %d\n", prop, ret);
+ return ret;
+}
+
+static int arizona_of_get_micd_configs(struct arizona *arizona,
+ const char *prop)
+{
+ int nconfigs;
+ int i, j;
+ int ret = 0;
+ u32 value;
+ struct arizona_micd_config *micd_configs;
+
+ nconfigs = arizona_of_get_u32_num_groups(arizona, prop, 3);
+ if (nconfigs < 0)
+ return nconfigs;
+
+ micd_configs = devm_kzalloc(arizona->dev,
+ nconfigs *
+ sizeof(struct arizona_micd_config),
+ GFP_KERNEL);
+
+ for (i = 0, j = 0; i < nconfigs; ++i) {
+ ret = of_property_read_u32_index(arizona->dev->of_node,
+ prop, j++, &value);
+ if (ret < 0)
+ goto error;
+ micd_configs[i].src = value;
+
+ ret = of_property_read_u32_index(arizona->dev->of_node,
+ prop, j++, &value);
+ if (ret < 0)
+ goto error;
+ micd_configs[i].bias = value;
+
+ ret = of_property_read_u32_index(arizona->dev->of_node,
+ prop, j++, &value);
+ if (ret < 0)
+ goto error;
+ micd_configs[i].gpio = value;
+ }
+
+ arizona->pdata.micd_configs = micd_configs;
+ arizona->pdata.num_micd_configs = nconfigs;
+
+ return ret;
+
+error:
+ devm_kfree(arizona->dev, micd_configs);
+ dev_err(arizona->dev, "DT property %s is malformed: %d\n", prop, ret);
+ return ret;
+}
+
static int arizona_of_get_core_pdata(struct arizona *arizona)
{
struct arizona_pdata *pdata = &arizona->pdata;
pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
+ arizona_of_get_micd_ranges(arizona, "wlf,micd-ranges");
+ arizona_of_get_micd_configs(arizona, "wlf,micd-configs");
+
ret = of_property_read_u32_array(arizona->dev->of_node,
"wlf,gpio-defaults",
arizona->pdata.gpio_defaults,