tegrakernel/kernel/nvidia/drivers/i2c/busses/i2c-tegra-hv-common.h

158 lines
4.4 KiB
C

/*
* Copyright (c) 2015-2017, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __I2C_LIB_HV_H__
#define __I2C_LIB_HV_H__
#ifdef CONFIG_TEGRA_HV_MANAGER
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/tegra-ivc.h>
#include <linux/list.h>
#include <linux/workqueue.h>
typedef void (*i2c_isr_handler)(void *context);
struct tegra_hv_i2c_comm_chan;
int hv_i2c_transfer(struct tegra_hv_i2c_comm_chan *comm_chan, phys_addr_t base,
int addr, int read, uint8_t *buf, size_t len, int *err,
int seq_no, uint32_t flags);
int hv_i2c_get_max_payload(struct tegra_hv_i2c_comm_chan *comm_chan,
phys_addr_t base, uint32_t *max_payload, int *err);
int hv_i2c_comm_chan_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan,
phys_addr_t base);
void hv_i2c_comm_chan_free(struct tegra_hv_i2c_comm_chan *comm_chan);
void hv_i2c_comm_suspend(struct tegra_hv_i2c_comm_chan *comm_chan);
void hv_i2c_comm_resume(struct tegra_hv_i2c_comm_chan *comm_chan);
void *hv_i2c_comm_init(struct device *dev, i2c_isr_handler handler,
void *data);
void tegra_hv_i2c_poll_cleanup(struct tegra_hv_i2c_comm_chan *comm_chan);
#define MAX_COMM_CHANS 10
enum i2c_ivc_msg_t {
I2C_READ,
I2C_READ_RESPONSE,
I2C_WRITE,
I2C_WRITE_RESPONSE,
I2C_GET_MAX_PAYLOAD,
I2C_GET_MAX_PAYLOAD_RESPONSE,
I2C_CLEANUP,
I2C_CLEANUP_RESPONSE,
I2C_INVALID,
};
enum i2c_rx_state_t {
I2C_RX_INIT,
I2C_RX_PENDING,
I2C_RX_PENDING_CLEANUP,
};
#define HV_I2C_FLAGS_HIGHSPEED_MODE (1<<22)
#define HV_I2C_FLAGS_CONT_ON_NAK (1<<21)
#define HV_I2C_FLAGS_SEND_START_BYTE (1<<20)
#define HV_I2C_FLAGS_10BIT_ADDR (1<<18)
#define HV_I2C_FLAGS_IE_ENABLE (1<<17)
#define HV_I2C_FLAGS_REPEAT_START (1<<16)
#define HV_I2C_FLAGS_CONTINUE_XFER (1<<15)
struct i2c_ivc_msg_common {
uint32_t s_marker;
uint32_t msg_type;
int32_t comm_chan_id;
uint32_t controller_instance;
uint32_t err;
uint32_t e_marker;
};
struct i2c_ivc_msg_tx_rx_hdr {
int32_t seq_no;
uint32_t slave_address;
uint32_t buf_len;
uint32_t flags;
};
struct i2c_ivc_msg_tx_rx {
struct i2c_ivc_msg_tx_rx_hdr fixed;
uint8_t buffer[4096];
};
struct i2c_ivc_msg_max_payload {
uint32_t max_payload;
};
struct i2c_ivc_msg {
struct i2c_ivc_msg_common hdr;
union {
struct i2c_ivc_msg_tx_rx m;
struct i2c_ivc_msg_max_payload p;
} body;
};
#define I2C_IVC_COMMON_HEADER_LEN sizeof(struct i2c_ivc_msg_common)
#define i2c_ivc_start_marker(_msg_ptr) (_msg_ptr->hdr.s_marker)
#define i2c_ivc_end_marker(_msg_ptr) (_msg_ptr->hdr.e_marker)
#define i2c_ivc_chan_id(_msg_ptr) (_msg_ptr->hdr.comm_chan_id)
#define i2c_ivc_controller_instance(_msg_ptr) \
(_msg_ptr->hdr.controller_instance)
#define i2c_ivc_msg_type(_msg_ptr) (_msg_ptr->hdr.msg_type)
#define i2c_ivc_error_field(_msg_ptr) (_msg_ptr->hdr.err)
#define i2c_ivc_message_seq_nr(_msg_ptr) \
(_msg_ptr->body.m.fixed.seq_no)
#define i2c_ivc_message_slave_addr(_msg_ptr) \
(_msg_ptr->body.m.fixed.slave_address)
#define i2c_ivc_message_buf_len(_msg_ptr) \
(_msg_ptr->body.m.fixed.buf_len)
#define i2c_ivc_message_flags(_msg_ptr) (_msg_ptr->body.m.fixed.flags)
#define i2c_ivc_message_buffer(_msg_ptr) \
(_msg_ptr->body.m.buffer[0])
#define i2c_ivc_max_payload_field(_msg_ptr) \
(_msg_ptr->body.p.max_payload)
struct tegra_hv_i2c_comm_dev;
/* channel is virtual abstraction over a single ivc queue
* each channel holds messages that are independent of other channels
* we allocate one channel per i2c adapter as these can operate in parallel
*/
struct tegra_hv_i2c_comm_chan {
struct tegra_hv_ivc_cookie *ivck;
struct device *dev;
int id;
i2c_isr_handler handler;
void *data;
void *rcvd_data;
size_t data_len;
int *rcvd_err;
enum i2c_rx_state_t rx_state;
struct tegra_hv_i2c_comm_dev *hv_comm_dev;
spinlock_t lock;
};
struct tegra_hv_i2c_comm_dev {
uint32_t queue_id;
struct tegra_hv_ivc_cookie *ivck;
spinlock_t ivck_tx_lock;
spinlock_t lock;
struct hlist_node list;
struct work_struct work;
struct tegra_hv_i2c_comm_chan *hv_comm_chan[MAX_COMM_CHANS];
};
#endif
#endif