ts3a227e.c 10.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * TS3A227E Autonomous Audio Accessory Detection and Configuration Switch
 *
 * Copyright (C) 2014 Google, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/regmap.h>
F
Fang, Yang A 已提交
18
#include <linux/acpi.h>
19 20 21 22 23

#include <sound/core.h>
#include <sound/jack.h>
#include <sound/soc.h>

24 25
#include "ts3a227e.h"

26
struct ts3a227e {
27
	struct device *dev;
28 29 30 31 32
	struct regmap *regmap;
	struct snd_soc_jack *jack;
	bool plugged;
	bool mic_present;
	unsigned int buttons_held;
33
	int irq;
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
};

/* Button values to be reported on the jack */
static const int ts3a227e_buttons[] = {
	SND_JACK_BTN_0,
	SND_JACK_BTN_1,
	SND_JACK_BTN_2,
	SND_JACK_BTN_3,
};

#define TS3A227E_NUM_BUTTONS 4
#define TS3A227E_JACK_MASK (SND_JACK_HEADPHONE | \
			    SND_JACK_MICROPHONE | \
			    SND_JACK_BTN_0 | \
			    SND_JACK_BTN_1 | \
			    SND_JACK_BTN_2 | \
			    SND_JACK_BTN_3)

/* TS3A227E registers */
#define TS3A227E_REG_DEVICE_ID		0x00
#define TS3A227E_REG_INTERRUPT		0x01
#define TS3A227E_REG_KP_INTERRUPT	0x02
#define TS3A227E_REG_INTERRUPT_DISABLE	0x03
#define TS3A227E_REG_SETTING_1		0x04
#define TS3A227E_REG_SETTING_2		0x05
#define TS3A227E_REG_SETTING_3		0x06
#define TS3A227E_REG_SWITCH_CONTROL_1	0x07
#define TS3A227E_REG_SWITCH_CONTROL_2	0x08
#define TS3A227E_REG_SWITCH_STATUS_1	0x09
#define TS3A227E_REG_SWITCH_STATUS_2	0x0a
#define TS3A227E_REG_ACCESSORY_STATUS	0x0b
#define TS3A227E_REG_ADC_OUTPUT		0x0c
#define TS3A227E_REG_KP_THRESHOLD_1	0x0d
#define TS3A227E_REG_KP_THRESHOLD_2	0x0e
#define TS3A227E_REG_KP_THRESHOLD_3	0x0f

/* TS3A227E_REG_INTERRUPT 0x01 */
#define INS_REM_EVENT 0x01
#define DETECTION_COMPLETE_EVENT 0x02

/* TS3A227E_REG_KP_INTERRUPT 0x02 */
#define PRESS_MASK(idx) (0x01 << (2 * (idx)))
#define RELEASE_MASK(idx) (0x02 << (2 * (idx)))

/* TS3A227E_REG_INTERRUPT_DISABLE 0x03 */
#define INS_REM_INT_DISABLE 0x01
#define DETECTION_COMPLETE_INT_DISABLE 0x02
#define ADC_COMPLETE_INT_DISABLE 0x04
#define INTB_DISABLE 0x08

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

87 88 89 90
/* TS3A227E_REG_SETTING_3 0x06 */
#define MICBIAS_SETTING_SFT (3)
#define MICBIAS_SETTING_MASK (0x7 << MICBIAS_SETTING_SFT)

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
/* TS3A227E_REG_ACCESSORY_STATUS  0x0b */
#define TYPE_3_POLE 0x01
#define TYPE_4_POLE_OMTP 0x02
#define TYPE_4_POLE_STANDARD 0x04
#define JACK_INSERTED 0x08
#define EITHER_MIC_MASK (TYPE_4_POLE_OMTP | TYPE_4_POLE_STANDARD)

static const struct reg_default ts3a227e_reg_defaults[] = {
	{ TS3A227E_REG_DEVICE_ID, 0x10 },
	{ TS3A227E_REG_INTERRUPT, 0x00 },
	{ TS3A227E_REG_KP_INTERRUPT, 0x00 },
	{ TS3A227E_REG_INTERRUPT_DISABLE, 0x08 },
	{ TS3A227E_REG_SETTING_1, 0x23 },
	{ TS3A227E_REG_SETTING_2, 0x00 },
	{ TS3A227E_REG_SETTING_3, 0x0e },
	{ TS3A227E_REG_SWITCH_CONTROL_1, 0x00 },
	{ TS3A227E_REG_SWITCH_CONTROL_2, 0x00 },
	{ TS3A227E_REG_SWITCH_STATUS_1, 0x0c },
	{ TS3A227E_REG_SWITCH_STATUS_2, 0x00 },
	{ TS3A227E_REG_ACCESSORY_STATUS, 0x00 },
	{ TS3A227E_REG_ADC_OUTPUT, 0x00 },
	{ TS3A227E_REG_KP_THRESHOLD_1, 0x20 },
	{ TS3A227E_REG_KP_THRESHOLD_2, 0x40 },
	{ TS3A227E_REG_KP_THRESHOLD_3, 0x68 },
};

static bool ts3a227e_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case TS3A227E_REG_DEVICE_ID ... TS3A227E_REG_KP_THRESHOLD_3:
		return true;
	default:
		return false;
	}
}

static bool ts3a227e_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case TS3A227E_REG_INTERRUPT_DISABLE ... TS3A227E_REG_SWITCH_CONTROL_2:
	case TS3A227E_REG_KP_THRESHOLD_1 ... TS3A227E_REG_KP_THRESHOLD_3:
		return true;
	default:
		return false;
	}
}

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_SWITCH_STATUS_1 ... TS3A227E_REG_ADC_OUTPUT:
		return true;
	default:
		return false;
	}
}

static void ts3a227e_jack_report(struct ts3a227e *ts3a227e)
{
	unsigned int i;
	int report = 0;

	if (!ts3a227e->jack)
		return;

	if (ts3a227e->plugged)
		report = SND_JACK_HEADPHONE;
	if (ts3a227e->mic_present)
		report |= SND_JACK_MICROPHONE;
	for (i = 0; i < TS3A227E_NUM_BUTTONS; i++) {
		if (ts3a227e->buttons_held & (1 << i))
			report |= ts3a227e_buttons[i];
	}
	snd_soc_jack_report(ts3a227e->jack, report, TS3A227E_JACK_MASK);
}

static void ts3a227e_new_jack_state(struct ts3a227e *ts3a227e, unsigned acc_reg)
{
	bool plugged, mic_present;

	plugged = !!(acc_reg & JACK_INSERTED);
	mic_present = plugged && !!(acc_reg & EITHER_MIC_MASK);

	ts3a227e->plugged = plugged;

	if (mic_present != ts3a227e->mic_present) {
		ts3a227e->mic_present = mic_present;
		ts3a227e->buttons_held = 0;
		if (mic_present) {
			/* Enable key press detection. */
			regmap_update_bits(ts3a227e->regmap,
					   TS3A227E_REG_SETTING_2,
					   KP_ENABLE, KP_ENABLE);
		}
	}
}

static irqreturn_t ts3a227e_interrupt(int irq, void *data)
{
	struct ts3a227e *ts3a227e = (struct ts3a227e *)data;
	struct regmap *regmap = ts3a227e->regmap;
	unsigned int int_reg, kp_int_reg, acc_reg, i;
195 196
	struct device *dev = ts3a227e->dev;
	int ret;
197 198

	/* Check for plug/unplug. */
199 200 201 202 203 204
	ret = regmap_read(regmap, TS3A227E_REG_INTERRUPT, &int_reg);
	if (ret) {
		dev_err(dev, "failed to clear interrupt ret=%d\n", ret);
		return IRQ_NONE;
	}

205 206 207 208 209 210
	if (int_reg & (DETECTION_COMPLETE_EVENT | INS_REM_EVENT)) {
		regmap_read(regmap, TS3A227E_REG_ACCESSORY_STATUS, &acc_reg);
		ts3a227e_new_jack_state(ts3a227e, acc_reg);
	}

	/* Report any key events. */
211 212 213 214 215 216
	ret = regmap_read(regmap, TS3A227E_REG_KP_INTERRUPT, &kp_int_reg);
	if (ret) {
		dev_err(dev, "failed to clear key interrupt ret=%d\n", ret);
		return IRQ_NONE;
	}

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
	for (i = 0; i < TS3A227E_NUM_BUTTONS; i++) {
		if (kp_int_reg & PRESS_MASK(i))
			ts3a227e->buttons_held |= (1 << i);
		if (kp_int_reg & RELEASE_MASK(i))
			ts3a227e->buttons_held &= ~(1 << i);
	}

	ts3a227e_jack_report(ts3a227e);

	return IRQ_HANDLED;
}

/**
 * ts3a227e_enable_jack_detect - Specify a jack for event reporting
 *
 * @component:  component to register the jack with
 * @jack: jack to use to report headset and button events on
 *
 * After this function has been called the headset insert/remove and button
 * events 0-3 will be routed to the given jack.  Jack can be null to stop
 * reporting.
 */
int ts3a227e_enable_jack_detect(struct snd_soc_component *component,
				struct snd_soc_jack *jack)
{
	struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component);

	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA);
245 246 247
	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271

	ts3a227e->jack = jack;
	ts3a227e_jack_report(ts3a227e);

	return 0;
}
EXPORT_SYMBOL_GPL(ts3a227e_enable_jack_detect);

static struct snd_soc_component_driver ts3a227e_soc_driver;

static const struct regmap_config ts3a227e_regmap_config = {
	.val_bits = 8,
	.reg_bits = 8,

	.max_register = TS3A227E_REG_KP_THRESHOLD_3,
	.readable_reg = ts3a227e_readable_reg,
	.writeable_reg = ts3a227e_writeable_reg,
	.volatile_reg = ts3a227e_volatile_reg,

	.cache_type = REGCACHE_RBTREE,
	.reg_defaults = ts3a227e_reg_defaults,
	.num_reg_defaults = ARRAY_SIZE(ts3a227e_reg_defaults),
};

272 273
static int ts3a227e_parse_device_property(struct ts3a227e *ts3a227e,
				struct device *dev)
274 275 276 277
{
	u32 micbias;
	int err;

278
	err = device_property_read_u32(dev, "ti,micbias", &micbias);
279 280 281 282 283 284 285 286 287
	if (!err) {
		regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_3,
			MICBIAS_SETTING_MASK,
			(micbias & 0x07) << MICBIAS_SETTING_SFT);
	}

	return 0;
}

288 289 290 291 292 293
static int ts3a227e_i2c_probe(struct i2c_client *i2c,
			      const struct i2c_device_id *id)
{
	struct ts3a227e *ts3a227e;
	struct device *dev = &i2c->dev;
	int ret;
294
	unsigned int acc_reg;
295 296 297 298 299 300

	ts3a227e = devm_kzalloc(&i2c->dev, sizeof(*ts3a227e), GFP_KERNEL);
	if (ts3a227e == NULL)
		return -ENOMEM;

	i2c_set_clientdata(i2c, ts3a227e);
301 302
	ts3a227e->dev = dev;
	ts3a227e->irq = i2c->irq;
303 304 305 306 307

	ts3a227e->regmap = devm_regmap_init_i2c(i2c, &ts3a227e_regmap_config);
	if (IS_ERR(ts3a227e->regmap))
		return PTR_ERR(ts3a227e->regmap);

308 309 310 311
	ret = ts3a227e_parse_device_property(ts3a227e, dev);
	if (ret) {
		dev_err(dev, "Failed to parse device property: %d\n", ret);
		return ret;
312 313
	}

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
	ret = devm_request_threaded_irq(dev, i2c->irq, NULL, ts3a227e_interrupt,
					IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					"TS3A227E", ts3a227e);
	if (ret) {
		dev_err(dev, "Cannot request irq %d (%d)\n", i2c->irq, ret);
		return ret;
	}

	ret = devm_snd_soc_register_component(&i2c->dev, &ts3a227e_soc_driver,
					      NULL, 0);
	if (ret)
		return ret;

	/* Enable interrupts except for ADC complete. */
	regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_INTERRUPT_DISABLE,
			   INTB_DISABLE | ADC_COMPLETE_INT_DISABLE,
			   ADC_COMPLETE_INT_DISABLE);

332 333 334 335 336
	/* Read jack status because chip might not trigger interrupt at boot. */
	regmap_read(ts3a227e->regmap, TS3A227E_REG_ACCESSORY_STATUS, &acc_reg);
	ts3a227e_new_jack_state(ts3a227e, acc_reg);
	ts3a227e_jack_report(ts3a227e);

337 338 339
	return 0;
}

340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
#ifdef CONFIG_PM_SLEEP
static int ts3a227e_suspend(struct device *dev)
{
	struct ts3a227e *ts3a227e = dev_get_drvdata(dev);

	dev_dbg(ts3a227e->dev, "suspend disable irq\n");
	disable_irq(ts3a227e->irq);

	return 0;
}

static int ts3a227e_resume(struct device *dev)
{
	struct ts3a227e *ts3a227e = dev_get_drvdata(dev);

	dev_dbg(ts3a227e->dev, "resume enable irq\n");
	enable_irq(ts3a227e->irq);

	return 0;
}
#endif

static const struct dev_pm_ops ts3a227e_pm = {
	SET_SYSTEM_SLEEP_PM_OPS(ts3a227e_suspend, ts3a227e_resume)
};

366 367 368 369 370 371 372 373 374 375 376 377
static const struct i2c_device_id ts3a227e_i2c_ids[] = {
	{ "ts3a227e", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ts3a227e_i2c_ids);

static const struct of_device_id ts3a227e_of_match[] = {
	{ .compatible = "ti,ts3a227e", },
	{ }
};
MODULE_DEVICE_TABLE(of, ts3a227e_of_match);

F
Fang, Yang A 已提交
378 379 380 381 382 383 384 385
#ifdef CONFIG_ACPI
static struct acpi_device_id ts3a227e_acpi_match[] = {
	{ "104C227E", 0 },
	{},
};
MODULE_DEVICE_TABLE(acpi, ts3a227e_acpi_match);
#endif

386 387 388
static struct i2c_driver ts3a227e_driver = {
	.driver = {
		.name = "ts3a227e",
389
		.pm = &ts3a227e_pm,
390
		.of_match_table = of_match_ptr(ts3a227e_of_match),
F
Fang, Yang A 已提交
391
		.acpi_match_table = ACPI_PTR(ts3a227e_acpi_match),
392 393 394 395 396 397 398 399 400
	},
	.probe = ts3a227e_i2c_probe,
	.id_table = ts3a227e_i2c_ids,
};
module_i2c_driver(ts3a227e_driver);

MODULE_DESCRIPTION("ASoC ts3a227e driver");
MODULE_AUTHOR("Dylan Reid <dgreid@chromium.org>");
MODULE_LICENSE("GPL v2");