linux/drivers/i2c/busses/i2c-sh_mobile.c

// SPDX-License-Identifier: GPL-2.0
/*
 * SuperH Mobile I2C Controller
 *
 * Copyright (C) 2014-19 Wolfram Sang <[email protected]>
 * Copyright (C) 2008 Magnus Damm
 *
 * Portions of the code based on out-of-tree driver i2c-sh7343.c
 * Copyright (c) 2006 Carlos Munoz <[email protected]>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>

/* Transmit operation:                                                      */
/*                                                                          */
/* 0 byte transmit                                                          */
/* BUS:     S     A8     ACK   P(*)                                         */
/* IRQ:       DTE   WAIT                                                    */
/* ICIC:                                                                    */
/* ICCR: 0x94       0x90                                                    */
/* ICDR:      A8                                                            */
/*                                                                          */
/* 1 byte transmit                                                          */
/* BUS:     S     A8     ACK   D8(1)   ACK   P(*)                           */
/* IRQ:       DTE   WAIT         WAIT                                       */
/* ICIC:      -DTE                                                          */
/* ICCR: 0x94                    0x90                                       */
/* ICDR:      A8    D8(1)                                                   */
/*                                                                          */
/* 2 byte transmit                                                          */
/* BUS:     S     A8     ACK   D8(1)   ACK   D8(2)   ACK   P(*)             */
/* IRQ:       DTE   WAIT         WAIT          WAIT                         */
/* ICIC:      -DTE                                                          */
/* ICCR: 0x94                                  0x90                         */
/* ICDR:      A8    D8(1)        D8(2)                                      */
/*                                                                          */
/* 3 bytes or more, +---------+ gets repeated                               */
/*                                                                          */
/*                                                                          */
/* Receive operation:                                                       */
/*                                                                          */
/* 0 byte receive - not supported since slave may hold SDA low              */
/*                                                                          */
/* 1 byte receive       [TX] | [RX]                                         */
/* BUS:     S     A8     ACK | D8(1)   ACK   P(*)                           */
/* IRQ:       DTE   WAIT     |   WAIT     DTE                               */
/* ICIC:      -DTE           |   +DTE                                       */
/* ICCR: 0x94       0x81     |   0xc0                                       */
/* ICDR:      A8             |            D8(1)                             */
/*                                                                          */
/* 2 byte receive        [TX]| [RX]                                         */
/* BUS:     S     A8     ACK | D8(1)   ACK   D8(2)   ACK   P(*)             */
/* IRQ:       DTE   WAIT     |   WAIT          WAIT     DTE                 */
/* ICIC:      -DTE           |                 +DTE                         */
/* ICCR: 0x94       0x81     |                 0xc0                         */
/* ICDR:      A8             |                 D8(1)    D8(2)               */
/*                                                                          */
/* 3 byte receive       [TX] | [RX]                                     (*) */
/* BUS:     S     A8     ACK | D8(1)   ACK   D8(2)   ACK   D8(3)   ACK    P */
/* IRQ:       DTE   WAIT     |   WAIT          WAIT         WAIT      DTE   */
/* ICIC:      -DTE           |                              +DTE            */
/* ICCR: 0x94       0x81     |                              0xc0            */
/* ICDR:      A8             |                 D8(1)        D8(2)     D8(3) */
/*                                                                          */
/* 4 bytes or more, this part is repeated    +---------+                    */
/*                                                                          */
/*                                                                          */
/* Interrupt order and BUSY flag                                            */
/*     ___                                                 _                */
/* SDA ___\___XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXAAAAAAAAA___/                 */
/* SCL      \_/1\_/2\_/3\_/4\_/5\_/6\_/7\_/8\___/9\_____/                   */
/*                                                                          */
/*        S   D7  D6  D5  D4  D3  D2  D1  D0              P(*)              */
/*                                           ___                            */
/* WAIT IRQ ________________________________/   \___________                */
/* TACK IRQ ____________________________________/   \_______                */
/* DTE  IRQ __________________________________________/   \_                */
/* AL   IRQ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                */
/*         _______________________________________________                  */
/* BUSY __/                                               \_                */
/*                                                                          */
/* (*) The STOP condition is only sent by the master at the end of the last */
/* I2C message or if the I2C_M_STOP flag is set. Similarly, the BUSY bit is */
/* only cleared after the STOP condition, so, between messages we have to   */
/* poll for the DTE bit.                                                    */
/*                                                                          */

enum sh_mobile_i2c_op {};

struct sh_mobile_i2c_data {};

struct sh_mobile_dt_config {};

#define IIC_FLAG_HAS_ICIC67

/* Register offsets */
#define ICDR
#define ICCR
#define ICSR
#define ICIC
#define ICCL
#define ICCH
#define ICSTART

/* Register bits */
#define ICCR_ICE
#define ICCR_RACK
#define ICCR_TRS
#define ICCR_BBSY
#define ICCR_SCP

#define ICSR_SCLM
#define ICSR_SDAM
#define SW_DONE
#define ICSR_BUSY
#define ICSR_AL
#define ICSR_TACK
#define ICSR_WAIT
#define ICSR_DTE

#define ICIC_ICCLB8
#define ICIC_ICCHB8
#define ICIC_TDMAE
#define ICIC_RDMAE
#define ICIC_ALE
#define ICIC_TACKE
#define ICIC_WAITE
#define ICIC_DTEE

#define ICSTART_ICSTART

static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
{}

static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs)
{}

static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
			unsigned char set, unsigned char clr)
{}

static u32 sh_mobile_i2c_iccl(unsigned long count_khz, u32 tLOW, u32 tf)
{}

static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf)
{}

static int sh_mobile_i2c_check_timing(struct sh_mobile_i2c_data *pd)
{}

static int sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
{}

static int sh_mobile_i2c_v2_init(struct sh_mobile_i2c_data *pd)
{}

static unsigned char i2c_op(struct sh_mobile_i2c_data *pd, enum sh_mobile_i2c_op op)
{}

static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd)
{}

static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd)
{}

static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
{}

static void sh_mobile_i2c_cleanup_dma(struct sh_mobile_i2c_data *pd, bool terminate)
{}

static void sh_mobile_i2c_dma_callback(void *data)
{}

static struct dma_chan *sh_mobile_i2c_request_dma_chan(struct device *dev,
				enum dma_transfer_direction dir, dma_addr_t port_addr)
{}

static void sh_mobile_i2c_xfer_dma(struct sh_mobile_i2c_data *pd)
{}

static void start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg,
		     bool do_init)
{}

static int poll_dte(struct sh_mobile_i2c_data *pd)
{}

static int poll_busy(struct sh_mobile_i2c_data *pd)
{}

static int sh_mobile_xfer(struct sh_mobile_i2c_data *pd,
			 struct i2c_msg *msgs, int num)
{}

static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
			      struct i2c_msg *msgs,
			      int num)
{}

static int sh_mobile_i2c_xfer_atomic(struct i2c_adapter *adapter,
				     struct i2c_msg *msgs,
				     int num)
{}

static u32 sh_mobile_i2c_func(struct i2c_adapter *adapter)
{}

static const struct i2c_algorithm sh_mobile_i2c_algorithm =;

static const struct i2c_adapter_quirks sh_mobile_i2c_quirks =;

/*
 * r8a7740 has an errata regarding I2C I/O pad reset needing this workaround.
 */
static int sh_mobile_i2c_r8a7740_workaround(struct sh_mobile_i2c_data *pd)
{}

static const struct sh_mobile_dt_config default_dt_config =;

static const struct sh_mobile_dt_config fast_clock_dt_config =;

static const struct sh_mobile_dt_config r8a7740_dt_config =;

static const struct of_device_id sh_mobile_i2c_dt_ids[] =;
MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids);

static void sh_mobile_i2c_release_dma(struct sh_mobile_i2c_data *pd)
{}

static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, struct sh_mobile_i2c_data *pd)
{}

static int sh_mobile_i2c_probe(struct platform_device *dev)
{}

static void sh_mobile_i2c_remove(struct platform_device *dev)
{}

static int sh_mobile_i2c_suspend(struct device *dev)
{}

static int sh_mobile_i2c_resume(struct device *dev)
{}

static const struct dev_pm_ops sh_mobile_i2c_pm_ops =;

static struct platform_driver sh_mobile_i2c_driver =;

static int __init sh_mobile_i2c_adap_init(void)
{}
subsys_initcall(sh_mobile_i2c_adap_init);

static void __exit sh_mobile_i2c_adap_exit(void)
{}
module_exit(sh_mobile_i2c_adap_exit);

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