brintos

brintos / linux-shallow public Read only

0
0
Text · 16.1 KiB · c3ae9d7 Raw
587 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * tusb1210.c - TUSB1210 USB ULPI PHY driver4 *5 * Copyright (C) 2015 Intel Corporation6 *7 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>8 */9#include <linux/module.h>10#include <linux/bitfield.h>11#include <linux/delay.h>12#include <linux/ulpi/driver.h>13#include <linux/ulpi/regs.h>14#include <linux/gpio/consumer.h>15#include <linux/phy/ulpi_phy.h>16#include <linux/power_supply.h>17#include <linux/property.h>18#include <linux/workqueue.h>19 20#define TI_VENDOR_ID		0x045121#define TI_DEVICE_TUSB1210	0x150722#define TI_DEVICE_TUSB1211	0x150823 24#define TUSB1211_POWER_CONTROL				0x3d25#define TUSB1211_POWER_CONTROL_SET			0x3e26#define TUSB1211_POWER_CONTROL_CLEAR			0x3f27#define TUSB1211_POWER_CONTROL_SW_CONTROL		BIT(0)28#define TUSB1211_POWER_CONTROL_DET_COMP			BIT(1)29#define TUSB1211_POWER_CONTROL_DP_VSRC_EN		BIT(6)30 31#define TUSB1210_VENDOR_SPECIFIC2			0x8032#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK		GENMASK(3, 0)33#define TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK		GENMASK(5, 4)34#define TUSB1210_VENDOR_SPECIFIC2_DP_MASK		BIT(6)35 36#define TUSB1211_VENDOR_SPECIFIC3			0x8537#define TUSB1211_VENDOR_SPECIFIC3_SET			0x8638#define TUSB1211_VENDOR_SPECIFIC3_CLEAR			0x8739#define TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET		BIT(4)40#define TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN	BIT(6)41 42#define TUSB1210_RESET_TIME_MS				5043 44#define TUSB1210_CHG_DET_MAX_RETRIES			545 46/* TUSB1210 charger detection work states */47enum tusb1210_chg_det_state {48	TUSB1210_CHG_DET_CONNECTING,49	TUSB1210_CHG_DET_START_DET,50	TUSB1210_CHG_DET_READ_DET,51	TUSB1210_CHG_DET_FINISH_DET,52	TUSB1210_CHG_DET_CONNECTED,53	TUSB1210_CHG_DET_DISCONNECTING,54	TUSB1210_CHG_DET_DISCONNECTING_DONE,55	TUSB1210_CHG_DET_DISCONNECTED,56};57 58struct tusb1210 {59	struct device *dev;60	struct phy *phy;61	struct gpio_desc *gpio_reset;62	struct gpio_desc *gpio_cs;63	u8 otg_ctrl;64	u8 vendor_specific2;65#ifdef CONFIG_POWER_SUPPLY66	enum power_supply_usb_type chg_type;67	enum tusb1210_chg_det_state chg_det_state;68	int chg_det_retries;69	struct delayed_work chg_det_work;70	struct notifier_block psy_nb;71	struct power_supply *psy;72#endif73};74 75static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)76{77	struct device *dev = tusb->dev;78	int ret;79 80	ret = ulpi_write(to_ulpi_dev(dev), reg, val);81	if (ret)82		dev_err(dev, "error %d writing val 0x%02x to reg 0x%02x\n", ret, val, reg);83 84	return ret;85}86 87static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val)88{89	struct device *dev = tusb->dev;90	int ret;91 92	ret = ulpi_read(to_ulpi_dev(dev), reg);93	if (ret >= 0) {94		*val = ret;95		ret = 0;96	} else {97		dev_err(dev, "error %d reading reg 0x%02x\n", ret, reg);98	}99 100	return ret;101}102 103static int tusb1210_power_on(struct phy *phy)104{105	struct tusb1210 *tusb = phy_get_drvdata(phy);106 107	gpiod_set_value_cansleep(tusb->gpio_reset, 1);108	gpiod_set_value_cansleep(tusb->gpio_cs, 1);109 110	msleep(TUSB1210_RESET_TIME_MS);111 112	/* Restore the optional eye diagram optimization value */113	tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, tusb->vendor_specific2);114 115	return 0;116}117 118static int tusb1210_power_off(struct phy *phy)119{120	struct tusb1210 *tusb = phy_get_drvdata(phy);121 122	gpiod_set_value_cansleep(tusb->gpio_reset, 0);123	gpiod_set_value_cansleep(tusb->gpio_cs, 0);124 125	return 0;126}127 128static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)129{130	struct tusb1210 *tusb = phy_get_drvdata(phy);131	int ret;132	u8 reg;133 134	ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &reg);135	if (ret < 0)136		return ret;137 138	switch (mode) {139	case PHY_MODE_USB_HOST:140		reg |= (ULPI_OTG_CTRL_DRVVBUS_EXT141			| ULPI_OTG_CTRL_ID_PULLUP142			| ULPI_OTG_CTRL_DP_PULLDOWN143			| ULPI_OTG_CTRL_DM_PULLDOWN);144		tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);145		reg |= ULPI_OTG_CTRL_DRVVBUS;146		break;147	case PHY_MODE_USB_DEVICE:148		reg &= ~(ULPI_OTG_CTRL_DRVVBUS149			 | ULPI_OTG_CTRL_DP_PULLDOWN150			 | ULPI_OTG_CTRL_DM_PULLDOWN);151		tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);152		reg &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;153		break;154	default:155		/* nothing */156		return 0;157	}158 159	tusb->otg_ctrl = reg;160	return tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);161}162 163#ifdef CONFIG_POWER_SUPPLY164static const char * const tusb1210_chg_det_states[] = {165	"CHG_DET_CONNECTING",166	"CHG_DET_START_DET",167	"CHG_DET_READ_DET",168	"CHG_DET_FINISH_DET",169	"CHG_DET_CONNECTED",170	"CHG_DET_DISCONNECTING",171	"CHG_DET_DISCONNECTING_DONE",172	"CHG_DET_DISCONNECTED",173};174 175static void tusb1210_reset(struct tusb1210 *tusb)176{177	gpiod_set_value_cansleep(tusb->gpio_reset, 0);178	usleep_range(200, 500);179	gpiod_set_value_cansleep(tusb->gpio_reset, 1);180}181 182static void tusb1210_chg_det_set_type(struct tusb1210 *tusb,183				      enum power_supply_usb_type type)184{185	dev_dbg(tusb->dev, "charger type: %d\n", type);186	tusb->chg_type = type;187	tusb->chg_det_retries = 0;188	power_supply_changed(tusb->psy);189}190 191static void tusb1210_chg_det_set_state(struct tusb1210 *tusb,192				       enum tusb1210_chg_det_state new_state,193				       int delay_ms)194{195	if (delay_ms)196		dev_dbg(tusb->dev, "chg_det new state %s in %d ms\n",197			tusb1210_chg_det_states[new_state], delay_ms);198 199	tusb->chg_det_state = new_state;200	mod_delayed_work(system_long_wq, &tusb->chg_det_work,201			 msecs_to_jiffies(delay_ms));202}203 204static void tusb1210_chg_det_handle_ulpi_error(struct tusb1210 *tusb)205{206	tusb1210_reset(tusb);207	if (tusb->chg_det_retries < TUSB1210_CHG_DET_MAX_RETRIES) {208		tusb->chg_det_retries++;209		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET,210					   TUSB1210_RESET_TIME_MS);211	} else {212		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET,213					   TUSB1210_RESET_TIME_MS);214	}215}216 217/*218 * Boards using a TUSB121x for charger-detection have 3 power_supply class devs:219 *220 * tusb1211-charger-detect(1) -> charger -> fuel-gauge221 *222 * To determine if an USB charger is connected to the board, the online prop of223 * the charger psy needs to be read. Since the tusb1211-charger-detect psy is224 * the start of the supplier -> supplied-to chain, power_supply_am_i_supplied()225 * cannot be used here.226 *227 * Instead, below is a list of the power_supply names of known chargers for228 * these boards and the charger psy is looked up by name from this list.229 *230 * (1) modelling the external USB charger231 */232static const char * const tusb1210_chargers[] = {233	"bq24190-charger",234};235 236static bool tusb1210_get_online(struct tusb1210 *tusb)237{238	struct power_supply *charger = NULL;239	union power_supply_propval val;240	bool online = false;241	int i, ret;242 243	for (i = 0; i < ARRAY_SIZE(tusb1210_chargers) && !charger; i++)244		charger = power_supply_get_by_name(tusb1210_chargers[i]);245 246	if (!charger)247		return false;248 249	ret = power_supply_get_property(charger, POWER_SUPPLY_PROP_ONLINE, &val);250	if (ret == 0)251		online = val.intval;252 253	power_supply_put(charger);254 255	return online;256}257 258static void tusb1210_chg_det_work(struct work_struct *work)259{260	struct tusb1210 *tusb = container_of(work, struct tusb1210, chg_det_work.work);261	bool vbus_present = tusb1210_get_online(tusb);262	int ret;263	u8 val;264 265	dev_dbg(tusb->dev, "chg_det state %s vbus_present %d\n",266		tusb1210_chg_det_states[tusb->chg_det_state], vbus_present);267 268	switch (tusb->chg_det_state) {269	case TUSB1210_CHG_DET_CONNECTING:270		tusb->chg_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;271		tusb->chg_det_retries = 0;272		/* Power on USB controller for ulpi_read()/_write() */273		ret = pm_runtime_resume_and_get(tusb->dev->parent);274		if (ret < 0) {275			dev_err(tusb->dev, "error %d runtime-resuming\n", ret);276			/* Should never happen, skip charger detection */277			tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);278			return;279		}280		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_START_DET, 0);281		break;282	case TUSB1210_CHG_DET_START_DET:283		/*284		 * Use the builtin charger detection FSM to keep things simple.285		 * This only detects DCP / SDP. This is good enough for the few286		 * boards which actually rely on the phy for charger detection.287		 */288		mutex_lock(&tusb->phy->mutex);289		ret = tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_SET,290					  TUSB1211_VENDOR_SPECIFIC3_SW_USB_DET);291		mutex_unlock(&tusb->phy->mutex);292		if (ret) {293			tusb1210_chg_det_handle_ulpi_error(tusb);294			break;295		}296 297		/* Wait 400 ms for the charger detection FSM to finish */298		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_READ_DET, 400);299		break;300	case TUSB1210_CHG_DET_READ_DET:301		mutex_lock(&tusb->phy->mutex);302		ret = tusb1210_ulpi_read(tusb, TUSB1211_POWER_CONTROL, &val);303		mutex_unlock(&tusb->phy->mutex);304		if (ret) {305			tusb1210_chg_det_handle_ulpi_error(tusb);306			break;307		}308 309		if (val & TUSB1211_POWER_CONTROL_DET_COMP)310			tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_DCP);311		else312			tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_SDP);313 314		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_FINISH_DET, 0);315		break;316	case TUSB1210_CHG_DET_FINISH_DET:317		mutex_lock(&tusb->phy->mutex);318 319		/* Set SW_CONTROL to stop the charger-det FSM */320		ret = tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_SET,321					  TUSB1211_POWER_CONTROL_SW_CONTROL);322 323		/* Clear DP_VSRC_EN which may have been enabled by the charger-det FSM */324		ret |= tusb1210_ulpi_write(tusb, TUSB1211_POWER_CONTROL_CLEAR,325					   TUSB1211_POWER_CONTROL_DP_VSRC_EN);326 327		/* Clear CHGD_IDP_SRC_EN (may have been enabled by the charger-det FSM) */328		ret |= tusb1210_ulpi_write(tusb, TUSB1211_VENDOR_SPECIFIC3_CLEAR,329					   TUSB1211_VENDOR_SPECIFIC3_CHGD_IDP_SRC_EN);330 331		/* If any of the above fails reset the phy */332		if (ret) {333			tusb1210_reset(tusb);334			msleep(TUSB1210_RESET_TIME_MS);335		}336 337		/* Restore phy-parameters and OTG_CTRL register */338		tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, tusb->otg_ctrl);339		tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2,340				    tusb->vendor_specific2);341 342		mutex_unlock(&tusb->phy->mutex);343 344		pm_runtime_put(tusb->dev->parent);345		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTED, 0);346		break;347	case TUSB1210_CHG_DET_CONNECTED:348		if (!vbus_present)349			tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING, 0);350		break;351	case TUSB1210_CHG_DET_DISCONNECTING:352		/*353		 * The phy seems to take approx. 600ms longer then the charger354		 * chip (which is used to get vbus_present) to determine Vbus355		 * session end. Wait 800ms to ensure the phy has detected and356		 * signalled Vbus session end.357		 */358		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTING_DONE, 800);359		break;360	case TUSB1210_CHG_DET_DISCONNECTING_DONE:361		/*362		 * The phy often stops reacting to ulpi_read()/_write requests363		 * after a Vbus-session end. Reset it to work around this.364		 */365		tusb1210_reset(tusb);366		tusb1210_chg_det_set_type(tusb, POWER_SUPPLY_USB_TYPE_UNKNOWN);367		tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_DISCONNECTED, 0);368		break;369	case TUSB1210_CHG_DET_DISCONNECTED:370		if (vbus_present)371			tusb1210_chg_det_set_state(tusb, TUSB1210_CHG_DET_CONNECTING, 0);372		break;373	}374}375 376static int tusb1210_psy_notifier(struct notifier_block *nb,377	unsigned long event, void *ptr)378{379	struct tusb1210 *tusb = container_of(nb, struct tusb1210, psy_nb);380	struct power_supply *psy = ptr;381 382	if (psy != tusb->psy && psy->desc->type == POWER_SUPPLY_TYPE_USB)383		queue_delayed_work(system_long_wq, &tusb->chg_det_work, 0);384 385	return NOTIFY_OK;386}387 388static int tusb1210_psy_get_prop(struct power_supply *psy,389				 enum power_supply_property psp,390				 union power_supply_propval *val)391{392	struct tusb1210 *tusb = power_supply_get_drvdata(psy);393 394	switch (psp) {395	case POWER_SUPPLY_PROP_ONLINE:396		val->intval = tusb1210_get_online(tusb);397		break;398	case POWER_SUPPLY_PROP_USB_TYPE:399		val->intval = tusb->chg_type;400		break;401	case POWER_SUPPLY_PROP_CURRENT_MAX:402		if (tusb->chg_type == POWER_SUPPLY_USB_TYPE_DCP)403			val->intval = 2000000;404		else405			val->intval = 500000;406		break;407	default:408		return -EINVAL;409	}410 411	return 0;412}413 414static const enum power_supply_property tusb1210_psy_props[] = {415	POWER_SUPPLY_PROP_ONLINE,416	POWER_SUPPLY_PROP_USB_TYPE,417	POWER_SUPPLY_PROP_CURRENT_MAX,418};419 420static const struct power_supply_desc tusb1210_psy_desc = {421	.name = "tusb1211-charger-detect",422	.type = POWER_SUPPLY_TYPE_USB,423	.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |424		     BIT(POWER_SUPPLY_USB_TYPE_DCP) |425		     BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),426	.properties = tusb1210_psy_props,427	.num_properties = ARRAY_SIZE(tusb1210_psy_props),428	.get_property = tusb1210_psy_get_prop,429};430 431/* Setup charger detection if requested, on errors continue without chg-det */432static void tusb1210_probe_charger_detect(struct tusb1210 *tusb)433{434	struct power_supply_config psy_cfg = { .drv_data = tusb };435	struct device *dev = tusb->dev;436	struct ulpi *ulpi = to_ulpi_dev(dev);437	int ret;438 439	if (!device_property_read_bool(dev->parent, "linux,phy_charger_detect"))440		return;441 442	if (ulpi->id.product != TI_DEVICE_TUSB1211) {443		dev_err(dev, "error charger detection is only supported on the TUSB1211\n");444		return;445	}446 447	ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &tusb->otg_ctrl);448	if (ret)449		return;450 451	tusb->psy = power_supply_register(dev, &tusb1210_psy_desc, &psy_cfg);452	if (IS_ERR(tusb->psy))453		return;454 455	/*456	 * Delay initial run by 2 seconds to allow the charger driver,457	 * which is used to determine vbus_present, to load.458	 */459	tusb->chg_det_state = TUSB1210_CHG_DET_DISCONNECTED;460	INIT_DELAYED_WORK(&tusb->chg_det_work, tusb1210_chg_det_work);461	queue_delayed_work(system_long_wq, &tusb->chg_det_work, 2 * HZ);462 463	tusb->psy_nb.notifier_call = tusb1210_psy_notifier;464	power_supply_reg_notifier(&tusb->psy_nb);465}466 467static void tusb1210_remove_charger_detect(struct tusb1210 *tusb)468{469 470	if (!IS_ERR_OR_NULL(tusb->psy)) {471		power_supply_unreg_notifier(&tusb->psy_nb);472		cancel_delayed_work_sync(&tusb->chg_det_work);473		power_supply_unregister(tusb->psy);474	}475}476#else477static void tusb1210_probe_charger_detect(struct tusb1210 *tusb) { }478static void tusb1210_remove_charger_detect(struct tusb1210 *tusb) { }479#endif480 481static const struct phy_ops phy_ops = {482	.power_on = tusb1210_power_on,483	.power_off = tusb1210_power_off,484	.set_mode = tusb1210_set_mode,485	.owner = THIS_MODULE,486};487 488static int tusb1210_probe(struct ulpi *ulpi)489{490	struct device *dev = &ulpi->dev;491	struct tusb1210 *tusb;492	u8 val, reg;493	int ret;494 495	tusb = devm_kzalloc(dev, sizeof(*tusb), GFP_KERNEL);496	if (!tusb)497		return -ENOMEM;498 499	tusb->dev = dev;500 501	tusb->gpio_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);502	if (IS_ERR(tusb->gpio_reset))503		return PTR_ERR(tusb->gpio_reset);504 505	gpiod_set_value_cansleep(tusb->gpio_reset, 1);506 507	tusb->gpio_cs = devm_gpiod_get_optional(dev, "cs", GPIOD_OUT_LOW);508	if (IS_ERR(tusb->gpio_cs))509		return PTR_ERR(tusb->gpio_cs);510 511	gpiod_set_value_cansleep(tusb->gpio_cs, 1);512 513	/*514	 * VENDOR_SPECIFIC2 register in TUSB1210 can be used for configuring eye515	 * diagram optimization and DP/DM swap.516	 */517 518	ret = tusb1210_ulpi_read(tusb, TUSB1210_VENDOR_SPECIFIC2, &reg);519	if (ret)520		return ret;521 522	/* High speed output drive strength configuration */523	if (!device_property_read_u8(dev, "ihstx", &val))524		u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_IHSTX_MASK);525 526	/* High speed output impedance configuration */527	if (!device_property_read_u8(dev, "zhsdrv", &val))528		u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_ZHSDRV_MASK);529 530	/* DP/DM swap control */531	if (!device_property_read_u8(dev, "datapolarity", &val))532		u8p_replace_bits(&reg, val, (u8)TUSB1210_VENDOR_SPECIFIC2_DP_MASK);533 534	ret = tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, reg);535	if (ret)536		return ret;537 538	tusb->vendor_specific2 = reg;539 540	tusb1210_probe_charger_detect(tusb);541 542	tusb->phy = ulpi_phy_create(ulpi, &phy_ops);543	if (IS_ERR(tusb->phy)) {544		ret = PTR_ERR(tusb->phy);545		goto err_remove_charger;546	}547 548	phy_set_drvdata(tusb->phy, tusb);549	ulpi_set_drvdata(ulpi, tusb);550	return 0;551 552err_remove_charger:553	tusb1210_remove_charger_detect(tusb);554	return ret;555}556 557static void tusb1210_remove(struct ulpi *ulpi)558{559	struct tusb1210 *tusb = ulpi_get_drvdata(ulpi);560 561	ulpi_phy_destroy(ulpi, tusb->phy);562	tusb1210_remove_charger_detect(tusb);563}564 565static const struct ulpi_device_id tusb1210_ulpi_id[] = {566	{ TI_VENDOR_ID, TI_DEVICE_TUSB1210 },567	{ TI_VENDOR_ID, TI_DEVICE_TUSB1211 },568	{ },569};570MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id);571 572static struct ulpi_driver tusb1210_driver = {573	.id_table = tusb1210_ulpi_id,574	.probe = tusb1210_probe,575	.remove = tusb1210_remove,576	.driver = {577		.name = "tusb1210",578		.owner = THIS_MODULE,579	},580};581 582module_ulpi_driver(tusb1210_driver);583 584MODULE_AUTHOR("Intel Corporation");585MODULE_LICENSE("GPL v2");586MODULE_DESCRIPTION("TUSB1210 ULPI PHY driver");587