extcon-axp288.c (cbecf716ca618fd44feda6bd9a64a8179d031fc5) | extcon-axp288.c (968bd3f0388b8eaf6746336856348dc3ddf2ed39) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver 4 * 5 * Copyright (c) 2017-2018 Hans de Goede <hdegoede@redhat.com> 6 * Copyright (C) 2015 Intel Corporation 7 * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com> 8 */ --- 10 unchanged lines hidden (view full) --- 19#include <linux/extcon-provider.h> 20#include <linux/regmap.h> 21#include <linux/mfd/axp20x.h> 22#include <linux/usb/role.h> 23#include <linux/workqueue.h> 24 25#include <asm/cpu_device_id.h> 26#include <asm/intel-family.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * extcon-axp288.c - X-Power AXP288 PMIC extcon cable detection driver 4 * 5 * Copyright (c) 2017-2018 Hans de Goede <hdegoede@redhat.com> 6 * Copyright (C) 2015 Intel Corporation 7 * Author: Ramakrishna Pallala <ramakrishna.pallala@intel.com> 8 */ --- 10 unchanged lines hidden (view full) --- 19#include <linux/extcon-provider.h> 20#include <linux/regmap.h> 21#include <linux/mfd/axp20x.h> 22#include <linux/usb/role.h> 23#include <linux/workqueue.h> 24 25#include <asm/cpu_device_id.h> 26#include <asm/intel-family.h> |
27#include <asm/iosf_mbi.h> |
|
27 28/* Power source status register */ 29#define PS_STAT_VBUS_TRIGGER BIT(0) 30#define PS_STAT_BAT_CHRG_DIR BIT(2) 31#define PS_STAT_VBUS_ABOVE_VHOLD BIT(3) 32#define PS_STAT_VBUS_VALID BIT(4) 33#define PS_STAT_VBUS_PRESENT BIT(5) 34 --- 175 unchanged lines hidden (view full) --- 210 211static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) 212{ 213 int ret, stat, cfg; 214 u8 chrg_type; 215 unsigned int cable = info->previous_cable; 216 bool vbus_attach = false; 217 | 28 29/* Power source status register */ 30#define PS_STAT_VBUS_TRIGGER BIT(0) 31#define PS_STAT_BAT_CHRG_DIR BIT(2) 32#define PS_STAT_VBUS_ABOVE_VHOLD BIT(3) 33#define PS_STAT_VBUS_VALID BIT(4) 34#define PS_STAT_VBUS_PRESENT BIT(5) 35 --- 175 unchanged lines hidden (view full) --- 211 212static int axp288_handle_chrg_det_event(struct axp288_extcon_info *info) 213{ 214 int ret, stat, cfg; 215 u8 chrg_type; 216 unsigned int cable = info->previous_cable; 217 bool vbus_attach = false; 218 |
219 ret = iosf_mbi_block_punit_i2c_access(); 220 if (ret < 0) 221 return ret; 222 |
|
218 vbus_attach = axp288_get_vbus_attach(info); 219 if (!vbus_attach) 220 goto no_vbus; 221 222 /* Check charger detection completion status */ 223 ret = regmap_read(info->regmap, AXP288_BC_GLOBAL_REG, &cfg); 224 if (ret < 0) 225 goto dev_det_ret; --- 22 unchanged lines hidden (view full) --- 248 cable = EXTCON_CHG_USB_DCP; 249 break; 250 default: 251 dev_warn(info->dev, "unknown (reserved) bc detect result\n"); 252 cable = EXTCON_CHG_USB_SDP; 253 } 254 255no_vbus: | 223 vbus_attach = axp288_get_vbus_attach(info); 224 if (!vbus_attach) 225 goto no_vbus; 226 227 /* Check charger detection completion status */ 228 ret = regmap_read(info->regmap, AXP288_BC_GLOBAL_REG, &cfg); 229 if (ret < 0) 230 goto dev_det_ret; --- 22 unchanged lines hidden (view full) --- 253 cable = EXTCON_CHG_USB_DCP; 254 break; 255 default: 256 dev_warn(info->dev, "unknown (reserved) bc detect result\n"); 257 cable = EXTCON_CHG_USB_SDP; 258 } 259 260no_vbus: |
261 iosf_mbi_unblock_punit_i2c_access(); 262 |
|
256 extcon_set_state_sync(info->edev, info->previous_cable, false); 257 if (info->previous_cable == EXTCON_CHG_USB_SDP) 258 extcon_set_state_sync(info->edev, EXTCON_USB, false); 259 260 if (vbus_attach) { 261 extcon_set_state_sync(info->edev, cable, vbus_attach); 262 if (cable == EXTCON_CHG_USB_SDP) 263 extcon_set_state_sync(info->edev, EXTCON_USB, --- 6 unchanged lines hidden (view full) --- 270 info->vbus_attach = vbus_attach; 271 /* Setting the role can take a while */ 272 queue_work(system_long_wq, &info->role_work); 273 } 274 275 return 0; 276 277dev_det_ret: | 263 extcon_set_state_sync(info->edev, info->previous_cable, false); 264 if (info->previous_cable == EXTCON_CHG_USB_SDP) 265 extcon_set_state_sync(info->edev, EXTCON_USB, false); 266 267 if (vbus_attach) { 268 extcon_set_state_sync(info->edev, cable, vbus_attach); 269 if (cable == EXTCON_CHG_USB_SDP) 270 extcon_set_state_sync(info->edev, EXTCON_USB, --- 6 unchanged lines hidden (view full) --- 277 info->vbus_attach = vbus_attach; 278 /* Setting the role can take a while */ 279 queue_work(system_long_wq, &info->role_work); 280 } 281 282 return 0; 283 284dev_det_ret: |
285 iosf_mbi_unblock_punit_i2c_access(); 286 |
|
278 if (ret < 0) 279 dev_err(info->dev, "failed to detect BC Mod\n"); 280 281 return ret; 282} 283 284static int axp288_extcon_id_evt(struct notifier_block *nb, 285 unsigned long event, void *param) --- 14 unchanged lines hidden (view full) --- 300 301 ret = axp288_handle_chrg_det_event(info); 302 if (ret < 0) 303 dev_err(info->dev, "failed to handle the interrupt\n"); 304 305 return IRQ_HANDLED; 306} 307 | 287 if (ret < 0) 288 dev_err(info->dev, "failed to detect BC Mod\n"); 289 290 return ret; 291} 292 293static int axp288_extcon_id_evt(struct notifier_block *nb, 294 unsigned long event, void *param) --- 14 unchanged lines hidden (view full) --- 309 310 ret = axp288_handle_chrg_det_event(info); 311 if (ret < 0) 312 dev_err(info->dev, "failed to handle the interrupt\n"); 313 314 return IRQ_HANDLED; 315} 316 |
308static void axp288_extcon_enable(struct axp288_extcon_info *info) | 317static int axp288_extcon_enable(struct axp288_extcon_info *info) |
309{ | 318{ |
319 int ret = 0; 320 321 ret = iosf_mbi_block_punit_i2c_access(); 322 if (ret < 0) 323 return ret; 324 |
|
310 regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, 311 BC_GLOBAL_RUN, 0); 312 /* Enable the charger detection logic */ 313 regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, 314 BC_GLOBAL_RUN, BC_GLOBAL_RUN); | 325 regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, 326 BC_GLOBAL_RUN, 0); 327 /* Enable the charger detection logic */ 328 regmap_update_bits(info->regmap, AXP288_BC_GLOBAL_REG, 329 BC_GLOBAL_RUN, BC_GLOBAL_RUN); |
330 331 iosf_mbi_unblock_punit_i2c_access(); 332 333 return ret; |
|
315} 316 317static void axp288_put_role_sw(void *data) 318{ 319 struct axp288_extcon_info *info = data; 320 321 cancel_work_sync(&info->role_work); 322 usb_role_switch_put(info->role_sw); --- 56 unchanged lines hidden (view full) --- 379 return -EPROBE_DEFER; 380 381 dev_info(dev, "controlling USB role\n"); 382 } else { 383 dev_info(dev, "controlling USB role based on Vbus presence\n"); 384 } 385 } 386 | 334} 335 336static void axp288_put_role_sw(void *data) 337{ 338 struct axp288_extcon_info *info = data; 339 340 cancel_work_sync(&info->role_work); 341 usb_role_switch_put(info->role_sw); --- 56 unchanged lines hidden (view full) --- 398 return -EPROBE_DEFER; 399 400 dev_info(dev, "controlling USB role\n"); 401 } else { 402 dev_info(dev, "controlling USB role based on Vbus presence\n"); 403 } 404 } 405 |
406 ret = iosf_mbi_block_punit_i2c_access(); 407 if (ret < 0) 408 return ret; 409 |
|
387 info->vbus_attach = axp288_get_vbus_attach(info); 388 389 axp288_extcon_log_rsi(info); 390 | 410 info->vbus_attach = axp288_get_vbus_attach(info); 411 412 axp288_extcon_log_rsi(info); 413 |
414 iosf_mbi_unblock_punit_i2c_access(); 415 |
|
391 /* Initialize extcon device */ 392 info->edev = devm_extcon_dev_allocate(&pdev->dev, 393 axp288_extcon_cables); 394 if (IS_ERR(info->edev)) { 395 dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); 396 return PTR_ERR(info->edev); 397 } 398 --- 37 unchanged lines hidden (view full) --- 436 437 /* Make sure the role-sw is set correctly before doing BC detection */ 438 if (info->role_sw) { 439 queue_work(system_long_wq, &info->role_work); 440 flush_work(&info->role_work); 441 } 442 443 /* Start charger cable type detection */ | 416 /* Initialize extcon device */ 417 info->edev = devm_extcon_dev_allocate(&pdev->dev, 418 axp288_extcon_cables); 419 if (IS_ERR(info->edev)) { 420 dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); 421 return PTR_ERR(info->edev); 422 } 423 --- 37 unchanged lines hidden (view full) --- 461 462 /* Make sure the role-sw is set correctly before doing BC detection */ 463 if (info->role_sw) { 464 queue_work(system_long_wq, &info->role_work); 465 flush_work(&info->role_work); 466 } 467 468 /* Start charger cable type detection */ |
444 axp288_extcon_enable(info); | 469 ret = axp288_extcon_enable(info); 470 if (ret < 0) 471 return ret; |
445 446 device_init_wakeup(dev, true); 447 platform_set_drvdata(pdev, info); 448 449 return 0; 450} 451 452static int __maybe_unused axp288_extcon_suspend(struct device *dev) --- 47 unchanged lines hidden --- | 472 473 device_init_wakeup(dev, true); 474 platform_set_drvdata(pdev, info); 475 476 return 0; 477} 478 479static int __maybe_unused axp288_extcon_suspend(struct device *dev) --- 47 unchanged lines hidden --- |