brintos

brintos / linux-shallow public Read only

0
0
Text · 17.6 KiB · 7382bec Raw
690 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * Driver for UCS1002 Programmable USB Port Power Controller4 *5 * Copyright (C) 2019 Zodiac Inflight Innovations6 */7#include <linux/bits.h>8#include <linux/freezer.h>9#include <linux/gpio/consumer.h>10#include <linux/i2c.h>11#include <linux/interrupt.h>12#include <linux/kernel.h>13#include <linux/kthread.h>14#include <linux/device.h>15#include <linux/module.h>16#include <linux/of.h>17#include <linux/of_irq.h>18#include <linux/power_supply.h>19#include <linux/regmap.h>20#include <linux/regulator/driver.h>21#include <linux/regulator/of_regulator.h>22 23/* UCS1002 Registers */24#define UCS1002_REG_CURRENT_MEASUREMENT	0x0025 26/*27 * The Total Accumulated Charge registers store the total accumulated28 * charge delivered from the VS source to a portable device. The total29 * value is calculated using four registers, from 01h to 04h. The bit30 * weighting of the registers is given in mA/hrs.31 */32#define UCS1002_REG_TOTAL_ACC_CHARGE	0x0133 34/* Other Status Register */35#define UCS1002_REG_OTHER_STATUS	0x0f36#  define F_ADET_PIN			BIT(4)37#  define F_CHG_ACT			BIT(3)38 39/* Interrupt Status */40#define UCS1002_REG_INTERRUPT_STATUS	0x1041#  define F_ERR				BIT(7)42#  define F_DISCHARGE_ERR		BIT(6)43#  define F_RESET			BIT(5)44#  define F_MIN_KEEP_OUT		BIT(4)45#  define F_TSD				BIT(3)46#  define F_OVER_VOLT			BIT(2)47#  define F_BACK_VOLT			BIT(1)48#  define F_OVER_ILIM			BIT(0)49 50/* Pin Status Register */51#define UCS1002_REG_PIN_STATUS		0x1452#  define UCS1002_PWR_STATE_MASK	0x0353#  define F_PWR_EN_PIN			BIT(6)54#  define F_M2_PIN			BIT(5)55#  define F_M1_PIN			BIT(4)56#  define F_EM_EN_PIN			BIT(3)57#  define F_SEL_PIN			BIT(2)58#  define F_ACTIVE_MODE_MASK		GENMASK(5, 3)59#  define F_ACTIVE_MODE_PASSTHROUGH	F_M2_PIN60#  define F_ACTIVE_MODE_DEDICATED	F_EM_EN_PIN61#  define F_ACTIVE_MODE_BC12_DCP	(F_M2_PIN | F_EM_EN_PIN)62#  define F_ACTIVE_MODE_BC12_SDP	F_M1_PIN63#  define F_ACTIVE_MODE_BC12_CDP	(F_M1_PIN | F_M2_PIN | F_EM_EN_PIN)64 65/* General Configuration Register */66#define UCS1002_REG_GENERAL_CFG		0x1567#  define F_RATION_EN			BIT(3)68 69/* Emulation Configuration Register */70#define UCS1002_REG_EMU_CFG		0x1671 72/* Switch Configuration Register */73#define UCS1002_REG_SWITCH_CFG		0x1774#  define F_PIN_IGNORE			BIT(7)75#  define F_EM_EN_SET			BIT(5)76#  define F_M2_SET			BIT(4)77#  define F_M1_SET			BIT(3)78#  define F_S0_SET			BIT(2)79#  define F_PWR_EN_SET			BIT(1)80#  define F_LATCH_SET			BIT(0)81#  define V_SET_ACTIVE_MODE_MASK	GENMASK(5, 3)82#  define V_SET_ACTIVE_MODE_PASSTHROUGH	F_M2_SET83#  define V_SET_ACTIVE_MODE_DEDICATED	F_EM_EN_SET84#  define V_SET_ACTIVE_MODE_BC12_DCP	(F_M2_SET | F_EM_EN_SET)85#  define V_SET_ACTIVE_MODE_BC12_SDP	F_M1_SET86#  define V_SET_ACTIVE_MODE_BC12_CDP	(F_M1_SET | F_M2_SET | F_EM_EN_SET)87 88/* Current Limit Register */89#define UCS1002_REG_ILIMIT		0x1990#  define UCS1002_ILIM_SW_MASK		GENMASK(3, 0)91 92/* Product ID */93#define UCS1002_REG_PRODUCT_ID		0xfd94#  define UCS1002_PRODUCT_ID		0x4e95 96/* Manufacture name */97#define UCS1002_MANUFACTURER		"SMSC"98 99struct ucs1002_info {100	struct power_supply *charger;101	struct i2c_client *client;102	struct regmap *regmap;103	struct regulator_desc *regulator_descriptor;104	struct regulator_dev *rdev;105	bool present;106	bool output_disable;107	struct delayed_work health_poll;108	int health;109 110};111 112static enum power_supply_property ucs1002_props[] = {113	POWER_SUPPLY_PROP_ONLINE,114	POWER_SUPPLY_PROP_CHARGE_NOW,115	POWER_SUPPLY_PROP_CURRENT_NOW,116	POWER_SUPPLY_PROP_CURRENT_MAX,117	POWER_SUPPLY_PROP_PRESENT, /* the presence of PED */118	POWER_SUPPLY_PROP_MANUFACTURER,119	POWER_SUPPLY_PROP_USB_TYPE,120	POWER_SUPPLY_PROP_HEALTH,121};122 123static int ucs1002_get_online(struct ucs1002_info *info,124			      union power_supply_propval *val)125{126	unsigned int reg;127	int ret;128 129	ret = regmap_read(info->regmap, UCS1002_REG_OTHER_STATUS, &reg);130	if (ret)131		return ret;132 133	val->intval = !!(reg & F_CHG_ACT);134 135	return 0;136}137 138static int ucs1002_get_charge(struct ucs1002_info *info,139			      union power_supply_propval *val)140{141	/*142	 * To fit within 32 bits some values are rounded (uA/h)143	 *144	 * For Total Accumulated Charge Middle Low Byte register, addr145	 * 03h, byte 2146	 *147	 *   B0: 0.01084 mA/h rounded to 11 uA/h148	 *   B1: 0.02169 mA/h rounded to 22 uA/h149	 *   B2: 0.04340 mA/h rounded to 43 uA/h150	 *   B3: 0.08676 mA/h rounded to 87 uA/h151	 *   B4: 0.17350 mA/h rounded to 173 uÁ/h152	 *153	 * For Total Accumulated Charge Low Byte register, addr 04h,154	 * byte 3155	 *156	 *   B6: 0.00271 mA/h rounded to 3 uA/h157	 *   B7: 0.005422 mA/h rounded to 5 uA/h158	 */159	static const int bit_weights_uAh[BITS_PER_TYPE(u32)] = {160		/*161		 * Bit corresponding to low byte (offset 0x04)162		 * B0 B1 B2 B3 B4 B5 B6 B7163		 */164		0, 0, 0, 0, 0, 0, 3, 5,165		/*166		 * Bit corresponding to middle low byte (offset 0x03)167		 * B0 B1 B2 B3 B4 B5 B6 B7168		 */169		11, 22, 43, 87, 173, 347, 694, 1388,170		/*171		 * Bit corresponding to middle high byte (offset 0x02)172		 * B0 B1 B2 B3 B4 B5 B6 B7173		 */174		2776, 5552, 11105, 22210, 44420, 88840, 177700, 355400,175		/*176		 * Bit corresponding to high byte (offset 0x01)177		 * B0 B1 B2 B3 B4 B5 B6 B7178		 */179		710700, 1421000, 2843000, 5685000, 11371000, 22742000,180		45484000, 90968000,181	};182	unsigned long total_acc_charger;183	unsigned int reg;184	int i, ret;185 186	ret = regmap_bulk_read(info->regmap, UCS1002_REG_TOTAL_ACC_CHARGE,187			       &reg, sizeof(u32));188	if (ret)189		return ret;190 191	total_acc_charger = be32_to_cpu(reg); /* BE as per offsets above */192	val->intval = 0;193 194	for_each_set_bit(i, &total_acc_charger, ARRAY_SIZE(bit_weights_uAh))195		val->intval += bit_weights_uAh[i];196 197	return 0;198}199 200static int ucs1002_get_current(struct ucs1002_info *info,201			       union power_supply_propval *val)202{203	/*204	 * The Current Measurement register stores the measured205	 * current value delivered to the portable device. The range206	 * is from 9.76 mA to 2.5 A.207	 */208	static const int bit_weights_uA[BITS_PER_TYPE(u8)] = {209		9760, 19500, 39000, 78100, 156200, 312300, 624600, 1249300,210	};211	unsigned long current_measurement;212	unsigned int reg;213	int i, ret;214 215	ret = regmap_read(info->regmap, UCS1002_REG_CURRENT_MEASUREMENT, &reg);216	if (ret)217		return ret;218 219	current_measurement = reg;220	val->intval = 0;221 222	for_each_set_bit(i, &current_measurement, ARRAY_SIZE(bit_weights_uA))223		val->intval += bit_weights_uA[i];224 225	return 0;226}227 228/*229 * The Current Limit register stores the maximum current used by the230 * port switch. The range is from 500mA to 2.5 A.231 */232static const u32 ucs1002_current_limit_uA[] = {233	500000, 900000, 1000000, 1200000, 1500000, 1800000, 2000000, 2500000,234};235 236static int ucs1002_get_max_current(struct ucs1002_info *info,237				   union power_supply_propval *val)238{239	unsigned int reg;240	int ret;241 242	if (info->output_disable) {243		val->intval = 0;244		return 0;245	}246 247	ret = regmap_read(info->regmap, UCS1002_REG_ILIMIT, &reg);248	if (ret)249		return ret;250 251	val->intval = ucs1002_current_limit_uA[reg & UCS1002_ILIM_SW_MASK];252 253	return 0;254}255 256static int ucs1002_set_max_current(struct ucs1002_info *info, u32 val)257{258	unsigned int reg;259	int ret, idx;260 261	if (val == 0) {262		info->output_disable = true;263		regulator_disable_regmap(info->rdev);264		return 0;265	}266 267	for (idx = 0; idx < ARRAY_SIZE(ucs1002_current_limit_uA); idx++) {268		if (val == ucs1002_current_limit_uA[idx])269			break;270	}271 272	if (idx == ARRAY_SIZE(ucs1002_current_limit_uA))273		return -EINVAL;274 275	ret = regmap_write(info->regmap, UCS1002_REG_ILIMIT, idx);276	if (ret)277		return ret;278	/*279	 * Any current limit setting exceeding the one set via ILIM280	 * pin will be rejected, so we read out freshly changed limit281	 * to make sure that it took effect.282	 */283	ret = regmap_read(info->regmap, UCS1002_REG_ILIMIT, &reg);284	if (ret)285		return ret;286 287	if (reg != idx)288		return -EINVAL;289 290	info->output_disable = false;291 292	if (info->rdev && info->rdev->use_count &&293	    !regulator_is_enabled_regmap(info->rdev))294		regulator_enable_regmap(info->rdev);295 296	return 0;297}298 299static int ucs1002_set_usb_type(struct ucs1002_info *info, int val)300{301	unsigned int mode;302 303	switch (val) {304	/*305	 * POWER_SUPPLY_USB_TYPE_UNKNOWN == 0, map this to dedicated for306	 * userspace API compatibility with older versions of this driver307	 * which mapped 0 to dedicated.308	 */309	case POWER_SUPPLY_USB_TYPE_UNKNOWN:310	case POWER_SUPPLY_USB_TYPE_PD:311		mode = V_SET_ACTIVE_MODE_DEDICATED;312		break;313	case POWER_SUPPLY_USB_TYPE_SDP:314		mode = V_SET_ACTIVE_MODE_BC12_SDP;315		break;316	case POWER_SUPPLY_USB_TYPE_DCP:317		mode = V_SET_ACTIVE_MODE_BC12_DCP;318		break;319	case POWER_SUPPLY_USB_TYPE_CDP:320		mode = V_SET_ACTIVE_MODE_BC12_CDP;321		break;322	default:323		return -EINVAL;324	}325 326	return regmap_update_bits(info->regmap, UCS1002_REG_SWITCH_CFG,327				  V_SET_ACTIVE_MODE_MASK, mode);328}329 330static int ucs1002_get_usb_type(struct ucs1002_info *info,331				union power_supply_propval *val)332{333	enum power_supply_usb_type type;334	unsigned int reg;335	int ret;336 337	ret = regmap_read(info->regmap, UCS1002_REG_PIN_STATUS, &reg);338	if (ret)339		return ret;340 341	switch (reg & F_ACTIVE_MODE_MASK) {342	default:343		type = POWER_SUPPLY_USB_TYPE_UNKNOWN;344		break;345	case F_ACTIVE_MODE_DEDICATED:346		type = POWER_SUPPLY_USB_TYPE_PD;347		break;348	case F_ACTIVE_MODE_BC12_SDP:349		type = POWER_SUPPLY_USB_TYPE_SDP;350		break;351	case F_ACTIVE_MODE_BC12_DCP:352		type = POWER_SUPPLY_USB_TYPE_DCP;353		break;354	case F_ACTIVE_MODE_BC12_CDP:355		type = POWER_SUPPLY_USB_TYPE_CDP;356		break;357	}358 359	val->intval = type;360 361	return 0;362}363 364static int ucs1002_get_property(struct power_supply *psy,365				enum power_supply_property psp,366				union power_supply_propval *val)367{368	struct ucs1002_info *info = power_supply_get_drvdata(psy);369 370	switch (psp) {371	case POWER_SUPPLY_PROP_ONLINE:372		return ucs1002_get_online(info, val);373	case POWER_SUPPLY_PROP_CHARGE_NOW:374		return ucs1002_get_charge(info, val);375	case POWER_SUPPLY_PROP_CURRENT_NOW:376		return ucs1002_get_current(info, val);377	case POWER_SUPPLY_PROP_CURRENT_MAX:378		return ucs1002_get_max_current(info, val);379	case POWER_SUPPLY_PROP_USB_TYPE:380		return ucs1002_get_usb_type(info, val);381	case POWER_SUPPLY_PROP_HEALTH:382		val->intval = info->health;383		return 0;384	case POWER_SUPPLY_PROP_PRESENT:385		val->intval = info->present;386		return 0;387	case POWER_SUPPLY_PROP_MANUFACTURER:388		val->strval = UCS1002_MANUFACTURER;389		return 0;390	default:391		return -EINVAL;392	}393}394 395static int ucs1002_set_property(struct power_supply *psy,396				enum power_supply_property psp,397				const union power_supply_propval *val)398{399	struct ucs1002_info *info = power_supply_get_drvdata(psy);400 401	switch (psp) {402	case POWER_SUPPLY_PROP_CURRENT_MAX:403		return ucs1002_set_max_current(info, val->intval);404	case POWER_SUPPLY_PROP_USB_TYPE:405		return ucs1002_set_usb_type(info, val->intval);406	default:407		return -EINVAL;408	}409}410 411static int ucs1002_property_is_writeable(struct power_supply *psy,412					 enum power_supply_property psp)413{414	switch (psp) {415	case POWER_SUPPLY_PROP_CURRENT_MAX:416	case POWER_SUPPLY_PROP_USB_TYPE:417		return true;418	default:419		return false;420	}421}422 423static const struct power_supply_desc ucs1002_charger_desc = {424	.name			= "ucs1002",425	.type			= POWER_SUPPLY_TYPE_USB,426	.usb_types		= BIT(POWER_SUPPLY_USB_TYPE_SDP) |427				  BIT(POWER_SUPPLY_USB_TYPE_CDP) |428				  BIT(POWER_SUPPLY_USB_TYPE_DCP) |429				  BIT(POWER_SUPPLY_USB_TYPE_PD)  |430				  BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),431	.get_property		= ucs1002_get_property,432	.set_property		= ucs1002_set_property,433	.property_is_writeable	= ucs1002_property_is_writeable,434	.properties		= ucs1002_props,435	.num_properties		= ARRAY_SIZE(ucs1002_props),436};437 438static void ucs1002_health_poll(struct work_struct *work)439{440	struct ucs1002_info *info = container_of(work, struct ucs1002_info,441						 health_poll.work);442	int ret;443	u32 reg;444 445	ret = regmap_read(info->regmap, UCS1002_REG_INTERRUPT_STATUS, &reg);446	if (ret)447		return;448 449	/* bad health and no status change, just schedule us again in a while */450	if ((reg & F_ERR) && info->health != POWER_SUPPLY_HEALTH_GOOD) {451		schedule_delayed_work(&info->health_poll,452				      msecs_to_jiffies(2000));453		return;454	}455 456	if (reg & F_TSD)457		info->health = POWER_SUPPLY_HEALTH_OVERHEAT;458	else if (reg & (F_OVER_VOLT | F_BACK_VOLT))459		info->health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;460	else if (reg & F_OVER_ILIM)461		info->health = POWER_SUPPLY_HEALTH_OVERCURRENT;462	else if (reg & (F_DISCHARGE_ERR | F_MIN_KEEP_OUT))463		info->health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;464	else465		info->health = POWER_SUPPLY_HEALTH_GOOD;466 467	sysfs_notify(&info->charger->dev.kobj, NULL, "health");468}469 470static irqreturn_t ucs1002_charger_irq(int irq, void *data)471{472	int ret, regval;473	bool present;474	struct ucs1002_info *info = data;475 476	present = info->present;477 478	ret = regmap_read(info->regmap, UCS1002_REG_OTHER_STATUS, &regval);479	if (ret)480		return IRQ_HANDLED;481 482	/* update attached status */483	info->present = regval & F_ADET_PIN;484 485	/* notify the change */486	if (present != info->present)487		power_supply_changed(info->charger);488 489	return IRQ_HANDLED;490}491 492static irqreturn_t ucs1002_alert_irq(int irq, void *data)493{494	struct ucs1002_info *info = data;495 496	mod_delayed_work(system_wq, &info->health_poll, 0);497 498	return IRQ_HANDLED;499}500 501static int ucs1002_regulator_enable(struct regulator_dev *rdev)502{503	struct ucs1002_info *info = rdev_get_drvdata(rdev);504 505	/*506	 * If the output is disabled due to 0 maximum current, just pretend the507	 * enable did work. The regulator will be enabled as soon as we get a508	 * a non-zero maximum current budget.509	 */510	if (info->output_disable)511		return 0;512 513	return regulator_enable_regmap(rdev);514}515 516static const struct regulator_ops ucs1002_regulator_ops = {517	.is_enabled	= regulator_is_enabled_regmap,518	.enable		= ucs1002_regulator_enable,519	.disable	= regulator_disable_regmap,520};521 522static const struct regulator_desc ucs1002_regulator_descriptor = {523	.name		= "ucs1002-vbus",524	.ops		= &ucs1002_regulator_ops,525	.type		= REGULATOR_VOLTAGE,526	.owner		= THIS_MODULE,527	.enable_reg	= UCS1002_REG_SWITCH_CFG,528	.enable_mask	= F_PWR_EN_SET,529	.enable_val	= F_PWR_EN_SET,530	.fixed_uV	= 5000000,531	.n_voltages	= 1,532};533 534static int ucs1002_probe(struct i2c_client *client)535{536	struct device *dev = &client->dev;537	struct power_supply_config charger_config = {};538	const struct regmap_config regmap_config = {539		.reg_bits = 8,540		.val_bits = 8,541	};542	struct regulator_config regulator_config = {};543	int irq_a_det, irq_alert, ret;544	struct ucs1002_info *info;545	unsigned int regval;546 547	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);548	if (!info)549		return -ENOMEM;550 551	info->regmap = devm_regmap_init_i2c(client, &regmap_config);552	ret = PTR_ERR_OR_ZERO(info->regmap);553	if (ret) {554		dev_err(dev, "Regmap initialization failed: %d\n", ret);555		return ret;556	}557 558	info->client = client;559 560	irq_a_det = of_irq_get_byname(dev->of_node, "a_det");561	irq_alert = of_irq_get_byname(dev->of_node, "alert");562 563	charger_config.of_node = dev->of_node;564	charger_config.drv_data = info;565 566	ret = regmap_read(info->regmap, UCS1002_REG_PRODUCT_ID, &regval);567	if (ret) {568		dev_err(dev, "Failed to read product ID: %d\n", ret);569		return ret;570	}571 572	if (regval != UCS1002_PRODUCT_ID) {573		dev_err(dev,574			"Product ID does not match (0x%02x != 0x%02x)\n",575			regval, UCS1002_PRODUCT_ID);576		return -ENODEV;577	}578 579	/* Enable charge rationing by default */580	ret = regmap_update_bits(info->regmap, UCS1002_REG_GENERAL_CFG,581				 F_RATION_EN, F_RATION_EN);582	if (ret) {583		dev_err(dev, "Failed to read general config: %d\n", ret);584		return ret;585	}586 587	/*588	 * Ignore the M1, M2, PWR_EN, and EM_EN pin states. Set active589	 * mode selection to BC1.2 CDP.590	 */591	ret = regmap_update_bits(info->regmap, UCS1002_REG_SWITCH_CFG,592				 V_SET_ACTIVE_MODE_MASK | F_PIN_IGNORE,593				 V_SET_ACTIVE_MODE_BC12_CDP | F_PIN_IGNORE);594	if (ret) {595		dev_err(dev, "Failed to configure default mode: %d\n", ret);596		return ret;597	}598	/*599	 * Be safe and set initial current limit to 500mA600	 */601	ret = ucs1002_set_max_current(info, 500000);602	if (ret) {603		dev_err(dev, "Failed to set max current default: %d\n", ret);604		return ret;605	}606 607	info->charger = devm_power_supply_register(dev, &ucs1002_charger_desc,608						   &charger_config);609	ret = PTR_ERR_OR_ZERO(info->charger);610	if (ret) {611		dev_err(dev, "Failed to register power supply: %d\n", ret);612		return ret;613	}614 615	ret = regmap_read(info->regmap, UCS1002_REG_PIN_STATUS, &regval);616	if (ret) {617		dev_err(dev, "Failed to read pin status: %d\n", ret);618		return ret;619	}620 621	info->regulator_descriptor =622		devm_kmemdup(dev, &ucs1002_regulator_descriptor,623			     sizeof(ucs1002_regulator_descriptor),624			     GFP_KERNEL);625	if (!info->regulator_descriptor)626		return -ENOMEM;627 628	info->regulator_descriptor->enable_is_inverted = !(regval & F_SEL_PIN);629 630	regulator_config.dev = dev;631	regulator_config.of_node = dev->of_node;632	regulator_config.regmap = info->regmap;633	regulator_config.driver_data = info;634 635	info->rdev = devm_regulator_register(dev, info->regulator_descriptor,636				       &regulator_config);637	ret = PTR_ERR_OR_ZERO(info->rdev);638	if (ret) {639		dev_err(dev, "Failed to register VBUS regulator: %d\n", ret);640		return ret;641	}642 643	info->health = POWER_SUPPLY_HEALTH_GOOD;644	INIT_DELAYED_WORK(&info->health_poll, ucs1002_health_poll);645 646	if (irq_a_det > 0) {647		ret = devm_request_threaded_irq(dev, irq_a_det, NULL,648						ucs1002_charger_irq,649						IRQF_ONESHOT,650						"ucs1002-a_det", info);651		if (ret) {652			dev_err(dev, "Failed to request A_DET threaded irq: %d\n",653				ret);654			return ret;655		}656	}657 658	if (irq_alert > 0) {659		ret = devm_request_irq(dev, irq_alert, ucs1002_alert_irq,660				       0,"ucs1002-alert", info);661		if (ret) {662			dev_err(dev, "Failed to request ALERT threaded irq: %d\n",663				ret);664			return ret;665		}666	}667 668	return 0;669}670 671static const struct of_device_id ucs1002_of_match[] = {672	{ .compatible = "microchip,ucs1002", },673	{ /* sentinel */ },674};675MODULE_DEVICE_TABLE(of, ucs1002_of_match);676 677static struct i2c_driver ucs1002_driver = {678	.driver = {679		   .name = "ucs1002",680		   .of_match_table = ucs1002_of_match,681	},682	.probe = ucs1002_probe,683};684module_i2c_driver(ucs1002_driver);685 686MODULE_DESCRIPTION("Microchip UCS1002 Programmable USB Port Power Controller");687MODULE_AUTHOR("Enric Balletbo Serra <enric.balletbo@collabora.com>");688MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");689MODULE_LICENSE("GPL");690