linux/drivers/i2c/busses/i2c-cht-wc.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Intel CHT Whiskey Cove PMIC I2C controller driver
 * Copyright (C) 2017 Hans de Goede <[email protected]>
 *
 * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
 * Copyright (C) 2011 - 2014 Intel Corporation. All rights reserved.
 */

#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/mfd/intel_soc_pmic.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/power/bq24190_charger.h>
#include <linux/power/bq25890_charger.h>
#include <linux/slab.h>

#define CHT_WC_I2C_CTRL
#define CHT_WC_I2C_CTRL_WR
#define CHT_WC_I2C_CTRL_RD
#define CHT_WC_I2C_CLIENT_ADDR
#define CHT_WC_I2C_REG_OFFSET
#define CHT_WC_I2C_WRDATA
#define CHT_WC_I2C_RDDATA

#define CHT_WC_EXTCHGRIRQ
#define CHT_WC_EXTCHGRIRQ_CLIENT_IRQ
#define CHT_WC_EXTCHGRIRQ_WRITE_IRQ
#define CHT_WC_EXTCHGRIRQ_READ_IRQ
#define CHT_WC_EXTCHGRIRQ_NACK_IRQ
#define CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK
#define CHT_WC_EXTCHGRIRQ_MSK

struct cht_wc_i2c_adap {};

static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
{}

static u32 cht_wc_i2c_adap_func(struct i2c_adapter *adap)
{}

static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
				      unsigned short flags, char read_write,
				      u8 command, int size,
				      union i2c_smbus_data *data)
{}

static const struct i2c_algorithm cht_wc_i2c_adap_algo =;

/*
 * We are an i2c-adapter which itself is part of an i2c-client. This means that
 * transfers done through us take adapter->bus_lock twice, once for our parent
 * i2c-adapter and once to take our own bus_lock. Lockdep does not like this
 * nested locking, to make lockdep happy in the case of busses with muxes, the
 * i2c-core's i2c_adapter_lock_bus function calls:
 * rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter));
 *
 * But i2c_adapter_depth only works when the direct parent of the adapter is
 * another adapter, as it is only meant for muxes. In our case there is an
 * i2c-client and MFD instantiated platform_device in the parent->child chain
 * between the 2 devices.
 *
 * So we override the default i2c_lock_operations and pass a hardcoded
 * depth of 1 to rt_mutex_lock_nested, to make lockdep happy.
 *
 * Note that if there were to be a mux attached to our adapter, this would
 * break things again since the i2c-mux code expects the root-adapter to have
 * a locking depth of 0. But we always have only 1 client directly attached
 * in the form of the Charger IC paired with the CHT Whiskey Cove PMIC.
 */
static void cht_wc_i2c_adap_lock_bus(struct i2c_adapter *adapter,
				 unsigned int flags)
{}

static int cht_wc_i2c_adap_trylock_bus(struct i2c_adapter *adapter,
				   unsigned int flags)
{}

static void cht_wc_i2c_adap_unlock_bus(struct i2c_adapter *adapter,
				   unsigned int flags)
{}

static const struct i2c_lock_operations cht_wc_i2c_adap_lock_ops =;

/**** irqchip for the client connected to the extchgr i2c adapter ****/
static void cht_wc_i2c_irq_lock(struct irq_data *data)
{}

static void cht_wc_i2c_irq_sync_unlock(struct irq_data *data)
{}

static void cht_wc_i2c_irq_enable(struct irq_data *data)
{}

static void cht_wc_i2c_irq_disable(struct irq_data *data)
{}

static const struct irq_chip cht_wc_i2c_irq_chip =;

/********** GPD Win / Pocket charger IC settings **********/
static const char * const bq24190_suppliers[] =;

static const struct property_entry bq24190_props[] =;

static const struct software_node bq24190_node =;

static struct regulator_consumer_supply fusb302_consumer =;

static const struct regulator_init_data bq24190_vbus_init_data =;

static struct bq24190_platform_data bq24190_pdata =;

static struct i2c_board_info gpd_win_board_info =;

/********** Xiaomi Mi Pad 2 charger IC settings  **********/
static struct regulator_consumer_supply bq2589x_vbus_consumer =;

static const struct regulator_init_data bq2589x_vbus_init_data =;

static struct bq25890_platform_data bq2589x_pdata =;

static const struct property_entry xiaomi_mipad2_props[] =;

static const struct software_node xiaomi_mipad2_node =;

static struct i2c_board_info xiaomi_mipad2_board_info =;

/********** Lenovo Yogabook YB1-X90F/-X91F/-X91L charger settings **********/
static const char * const lenovo_yb1_bq25892_suppliers[] =;

static const struct property_entry lenovo_yb1_bq25892_props[] =;

static const struct software_node lenovo_yb1_bq25892_node =;

static struct i2c_board_info lenovo_yogabook1_board_info =;

/********** Lenovo Yogabook YT3-X90F charger settings **********/
static const char * const lenovo_yt3_bq25892_1_suppliers[] =;

/*
 * bq25892 charger settings for the round li-ion cells in the hinge,
 * this is the main / biggest battery.
 */
static const struct property_entry lenovo_yt3_bq25892_1_props[] =;

static const struct software_node lenovo_yt3_bq25892_1_node =;

/* bq25892 charger for the round li-ion cells in the hinge */
static struct i2c_board_info lenovo_yoga_tab3_board_info =;

static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
{}

static void cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
{}

static const struct platform_device_id cht_wc_i2c_adap_id_table[] =;
MODULE_DEVICE_TABLE(platform, cht_wc_i2c_adap_id_table);

static struct platform_driver cht_wc_i2c_adap_driver =;
module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();