Unverified Commit 843e10b3 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: ts3a227e control debounce times

Merge series from Astrid Rost <astrid.rost@axis.com>:

Add debounce support to the ts3a227e driver.
parents 61eb0add 6a47412d
Loading
Loading
Loading
Loading
+94 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/ti,ts3a227e.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Texas Instruments TS3A227E
  Autonomous Audio Accessory Detection and Configuration Switch

maintainers:
  - Dylan Reid <dgreid@chromium.org>

description: |
  The TS3A227E detect headsets of 3-ring and 4-ring standards and
  switches automatically to route the microphone correctly. It also
  handles key press detection in accordance with the Android audio
  headset specification v1.0.

properties:
  compatible:
    enum:
      - ti,ts3a227e

  reg:
    const: 0x3b

  interrupts:
    maxItems: 1

  ti,micbias:
    $ref: /schemas/types.yaml#/definitions/uint32
    description: Intended MICBIAS voltage (datasheet section 9.6.7).
    enum:
      - 0 # 2.1 V
      - 1 # 2.2 V
      - 2 # 2.3 V
      - 3 # 2.4 V
      - 4 # 2.5 V
      - 5 # 2.6 V
      - 6 # 2.7 V
      - 7 # 2.8 V
    default: 1

  ti,debounce-release-ms:
    description: key release debounce time in ms (datasheet section 9.6.7).
    enum:
      - 0
      - 20
    default: 20

  ti,debounce-press-ms:
    description: key press debounce time in ms (datasheet section 9.6.7).
    enum:
      - 2
      - 40
      - 80
      - 120
    default: 80

  ti,debounce-insertion-ms:
    description: headset insertion debounce time in ms (datasheet section 9.6.5).
    enum:
      - 2
      - 30
      - 60
      - 90
      - 120
      - 150
      - 1000
      - 2000
    default: 90

required:
  - compatible
  - reg
  - interrupts

additionalProperties: false

examples:
  - |
    #include <dt-bindings/interrupt-controller/irq.h>
    i2c {
        #address-cells = <1>;
        #size-cells = <0>;
        codec: audio-controller@3b {
            compatible = "ti,ts3a227e";
            reg = <0x3b>;
            interrupt-parent = <&gpio1>;
            interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
        };
    };

...
+0 −30
Original line number Diff line number Diff line
Texas Instruments TS3A227E
Autonomous Audio Accessory Detection and Configuration Switch

The TS3A227E detect headsets of 3-ring and 4-ring standards and
switches automatically to route the microphone correctly.  It also
handles key press detection in accordance with the Android audio
headset specification v1.0.

Required properties:

 - compatible:		Should contain "ti,ts3a227e".
 - reg:			The i2c address. Should contain <0x3b>.
 - interrupts:		Interrupt number for /INT pin from the 227e

Optional properies:
 - ti,micbias:   Intended MICBIAS voltage (datasheet section 9.6.7).
      Select 0/1/2/3/4/5/6/7 to specify MICBIAS voltage
      2.1V/2.2V/2.3V/2.4V/2.5V/2.6V/2.7V/2.8V
      Default value is "1" (2.2V).

Examples:

	i2c {
		ts3a227e@3b {
			compatible = "ti,ts3a227e";
			reg = <0x3b>;
			interrupt-parent = <&gpio>;
			interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
		};
	};
+55 −6
Original line number Diff line number Diff line
@@ -78,12 +78,20 @@ static const int ts3a227e_buttons[] = {
#define ADC_COMPLETE_INT_DISABLE 0x04
#define INTB_DISABLE 0x08

/* TS3A227E_REG_SETTING_1 0x4 */
#define DEBOUNCE_INSERTION_SETTING_SFT (0)
#define DEBOUNCE_INSERTION_SETTING_MASK (0x7 << DEBOUNCE_PRESS_SETTING_SFT)

/* TS3A227E_REG_SETTING_2 0x05 */
#define KP_ENABLE 0x04

/* TS3A227E_REG_SETTING_3 0x06 */
#define MICBIAS_SETTING_SFT (3)
#define MICBIAS_SETTING_SFT 3
#define MICBIAS_SETTING_MASK (0x7 << MICBIAS_SETTING_SFT)
#define DEBOUNCE_RELEASE_SETTING_SFT 2
#define DEBOUNCE_RELEASE_SETTING_MASK (0x1 << DEBOUNCE_RELEASE_SETTING_SFT)
#define DEBOUNCE_PRESS_SETTING_SFT 0
#define DEBOUNCE_PRESS_SETTING_MASK (0x3 << DEBOUNCE_PRESS_SETTING_SFT)

/* TS3A227E_REG_ACCESSORY_STATUS  0x0b */
#define TYPE_3_POLE 0x01
@@ -136,7 +144,7 @@ static bool ts3a227e_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case TS3A227E_REG_INTERRUPT ... TS3A227E_REG_INTERRUPT_DISABLE:
	case TS3A227E_REG_SETTING_2:
	case TS3A227E_REG_SETTING_1 ... TS3A227E_REG_SETTING_2:
	case TS3A227E_REG_SWITCH_STATUS_1 ... TS3A227E_REG_ADC_OUTPUT:
		return true;
	default:
@@ -269,14 +277,55 @@ static const struct regmap_config ts3a227e_regmap_config = {
static int ts3a227e_parse_device_property(struct ts3a227e *ts3a227e,
				struct device *dev)
{
	u32 micbias;
	u32 value;
	u32 value_ms;
	u32 setting3_value = 0;
	u32 setting3_mask = 0;
	int err;

	err = device_property_read_u32(dev, "ti,micbias", &micbias);
	err = device_property_read_u32(dev, "ti,micbias", &value);
	if (!err) {
		setting3_mask = MICBIAS_SETTING_MASK;
		setting3_value = (value << MICBIAS_SETTING_SFT) &
				 MICBIAS_SETTING_MASK;
	}

	err = device_property_read_u32(dev, "ti,debounce-release-ms",
				       &value_ms);
	if (!err) {
		value = (value_ms > 10);
		setting3_mask |= DEBOUNCE_RELEASE_SETTING_MASK;
		setting3_value |= (value << DEBOUNCE_RELEASE_SETTING_SFT) &
				  DEBOUNCE_RELEASE_SETTING_MASK;
	}

	err = device_property_read_u32(dev, "ti,debounce-press-ms", &value_ms);
	if (!err) {
		value = (value_ms + 20) / 40;
		if (value > 3)
			value = 3;
		setting3_mask |= DEBOUNCE_PRESS_SETTING_MASK;
		setting3_value |= (value << DEBOUNCE_PRESS_SETTING_SFT) &
				  DEBOUNCE_PRESS_SETTING_MASK;
	}

	if (setting3_mask)
		regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_3,
			MICBIAS_SETTING_MASK,
			(micbias & 0x07) << MICBIAS_SETTING_SFT);
				   setting3_mask, setting3_value);

	err = device_property_read_u32(dev, "ti,debounce-insertion-ms",
				       &value_ms);
	if (!err) {
		if (value_ms < 165)
			value = (value_ms + 15) / 30;
		else if (value_ms < 1500)
			value = 6;
		else
			value = 7;
		regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_1,
				   DEBOUNCE_INSERTION_SETTING_MASK,
				   (value << DEBOUNCE_INSERTION_SETTING_SFT) &
					   DEBOUNCE_INSERTION_SETTING_MASK);
	}

	return 0;