drivers/mfd/arizona-spi.c

Source file repositories/reference/linux-study-clean/drivers/mfd/arizona-spi.c

File Facts

System
Linux kernel
Corpus path
drivers/mfd/arizona-spi.c
Extension
.c
Size
8492 bytes
Lines
297
Domain
Driver Families
Bucket
drivers/mfd
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret == -ENOENT) {
			dev_info_once(arizona->dev,
				      "Deferring probe till GPIO lookup is registered\n");
			ret = -EPROBE_DEFER;
		}
		return dev_err_probe(arizona->dev, ret, "getting reset GPIO\n");
	}

	return 0;
}

/*
 * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
 * Function A Play/Pause:           0 ohm
 * Function D Voice assistant:    135 ohm
 * Function B Volume Up           240 ohm
 * Function C Volume Down         470 ohm
 * Minimum Mic DC resistance     1000 ohm
 * Minimum Ear speaker impedance   16 ohm
 * Note the first max value below must be less then the min. speaker impedance,
 * to allow CTIA/OMTP detection to work. The other max values are the closest
 * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
 */
static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
	{ .max =  11, .key = KEY_PLAYPAUSE },
	{ .max = 186, .key = KEY_VOICECOMMAND },
	{ .max = 348, .key = KEY_VOLUMEUP },
	{ .max = 752, .key = KEY_VOLUMEDOWN },
};

static int arizona_spi_acpi_probe(struct arizona *arizona)
{
	struct acpi_device *adev = ACPI_COMPANION(arizona->dev);
	int ret;

	if (acpi_dev_hid_uid_match(adev, "10WM5102", NULL))
		ret = arizona_spi_acpi_android_probe(arizona);
	else
		ret = arizona_spi_acpi_windows_probe(arizona);

	if (ret)
		return ret;

	/*
	 * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING
	 * The IRQ line will stay low when a new IRQ event happens between reading
	 * the IRQ status flags and acknowledging them. When the IRQ line stays
	 * low like this the IRQ will never trigger again when its type is set
	 * to IRQF_TRIGGER_FALLING. Correct the IRQ trigger-type to fix this.
	 *
	 * Note theoretically it is possible that some boards are not capable
	 * of handling active low level interrupts. In that case setting the
	 * flag to IRQF_TRIGGER_FALLING would not be a bug (and we would need
	 * to work around this) but so far all known usages of IRQF_TRIGGER_FALLING
	 * are a bug in the board's DSDT.
	 */
	arizona->pdata.irq_flags = IRQF_TRIGGER_LOW;

	/* Wait 200 ms after jack insertion */
	arizona->pdata.micd_detect_debounce = 200;

	/* Use standard AOSP values for headset-button mappings */
	arizona->pdata.micd_ranges = arizona_micd_aosp_ranges;
	arizona->pdata.num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges);

	/* Use left headphone speaker for HP vs line-out detection */
	arizona->pdata.hpdet_channel = ARIZONA_ACCDET_MODE_HPL;

	return 0;
}

static const struct acpi_device_id arizona_acpi_match[] = {
	{
		.id = "WM510204",
		.driver_data = WM5102,
	},
	{
		.id = "WM510205",
		.driver_data = WM5102,
	},
	{
		.id = "10WM5102",
		.driver_data = WM5102,
	},
	{ }
};
MODULE_DEVICE_TABLE(acpi, arizona_acpi_match);
#else
static int arizona_spi_acpi_probe(struct arizona *arizona)
{

Annotation

Implementation Notes