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

// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas RIIC driver
 *
 * Copyright (C) 2013 Wolfram Sang <[email protected]>
 * Copyright (C) 2013 Renesas Solutions Corp.
 */

/*
 * This i2c core has a lot of interrupts, namely 8. We use their chaining as
 * some kind of state machine.
 *
 * 1) The main xfer routine kicks off a transmission by putting the start bit
 * (or repeated start) on the bus and enabling the transmit interrupt (TIE)
 * since we need to send the target address + RW bit in every case.
 *
 * 2) TIE sends target address + RW bit and selects how to continue.
 *
 * 3a) Write case: We keep utilizing TIE as long as we have data to send. If we
 * are done, we switch over to the transmission done interrupt (TEIE) and mark
 * the message as completed (includes sending STOP) there.
 *
 * 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is
 * needed to start clocking, then we keep receiving until we are done. Note
 * that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by
 * writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a
 * message to create the final NACK as sketched in the datasheet. This caused
 * some subtle races (when byte n was processed and byte n+1 was already
 * waiting), though, and I started with the safe approach.
 *
 * 4) If we got a NACK somewhere, we flag the error and stop the transmission
 * via NAKIE.
 *
 * Also check the comments in the interrupt routines for some gory details.
 */

#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>

#define ICCR1_ICE
#define ICCR1_IICRST
#define ICCR1_SOWP

#define ICCR2_BBSY
#define ICCR2_SP
#define ICCR2_RS
#define ICCR2_ST

#define ICMR1_CKS_MASK
#define ICMR1_BCWP
#define ICMR1_CKS(_x)

#define ICMR3_RDRFS
#define ICMR3_ACKWP
#define ICMR3_ACKBT

#define ICIER_TIE
#define ICIER_TEIE
#define ICIER_RIE
#define ICIER_NAKIE
#define ICIER_SPIE

#define ICSR2_NACKF

#define ICBR_RESERVED

#define RIIC_INIT_MSG

enum riic_reg_list {};

struct riic_of_data {};

struct riic_dev {};

struct riic_irq_desc {};

static inline void riic_writeb(struct riic_dev *riic, u8 val, u8 offset)
{}

static inline u8 riic_readb(struct riic_dev *riic, u8 offset)
{}

static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg)
{}

static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{}

static irqreturn_t riic_tdre_isr(int irq, void *data)
{}

static irqreturn_t riic_tend_isr(int irq, void *data)
{}

static irqreturn_t riic_rdrf_isr(int irq, void *data)
{}

static irqreturn_t riic_stop_isr(int irq, void *data)
{}

static u32 riic_func(struct i2c_adapter *adap)
{}

static const struct i2c_algorithm riic_algo =;

static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t)
{}

static struct riic_irq_desc riic_irqs[] =;

static void riic_reset_control_assert(void *data)
{}

static int riic_i2c_probe(struct platform_device *pdev)
{}

static void riic_i2c_remove(struct platform_device *pdev)
{}

static const struct riic_of_data riic_rz_a_info =;

static const struct riic_of_data riic_rz_v2h_info =;

static const struct of_device_id riic_i2c_dt_ids[] =;

static struct platform_driver riic_i2c_driver =;

module_platform_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();
MODULE_DEVICE_TABLE(of, riic_i2c_dt_ids);