first and last commit

This commit is contained in:
Chris Nutter committed 2023-07-08 13:03:17 -07:00
commit 1bf4efd552
2612 files changed
+636500

No files matched your search

+160
View File
@@ -0,0 +1,160 @@
/*
* Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
*
* This document is the property of Apple Computer, Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Computer, Inc.
*/
#include <debug.h>
#include <sys/menu.h>
#include <drivers/iic.h>
#if defined(WITH_MENU) && WITH_MENU
static int do_iic(int argc, struct cmd_arg *args)
{
if (!security_allow_modes(kSecurityModeHWAccess)) {
printf("Permission Denied\n");
return -1;
}
if (argc < 3) {
notenoughargs:
puts("not enough arguments.\n");
usage:
printf("%s read <bus> <iicaddr> <len>\n", args[0].str);
printf("%s readreg <bus> <iicaddr> <reg> <len>\n", args[0].str);
printf("%s creadreg <bus> <iicaddr> <reg> <len>\n", args[0].str);
printf("%s readreg16 <bus> <iicaddr> <reg> <len>\n", args[0].str);
printf("%s write <bus> <iicaddr> <data0> <data1> ...\n", args[0].str);
printf("%s probe <bus>\n", args[0].str);
return -1;
}
int bus = args[2].u;
int addr = args[3].u;
if (bus < 0 || bus > 3) {
puts("unsupported bus\n");
return -1;
}
if (!strcmp("read", args[1].str)) {
uint8_t data[64];
int err;
size_t len = args[4].u;
if (len == 0 || len > 64) {
puts("invalid len\n");
return -1;
}
err = iic_read(bus, addr, NULL, 0, data, len, IIC_NORMAL);
if (err < 0) {
printf("error %d reading from iic\n", err);
} else {
hexdump(data, len);
}
} else if (!strcmp("readreg", args[1].str)) {
uint8_t data[64];
uint8_t outdata;
int err;
size_t len = args[5].u;
if (argc < 6)
goto notenoughargs;
if (len == 0 || len > 64) {
puts("invalid len\n");
return -1;
}
outdata = args[4].u & 0xff;
err = iic_read(bus, addr, &outdata, 1, data, len, IIC_NORMAL);
if (err < 0) {
printf("error %d reading from iic\n", err);
} else {
hexdump(data, len);
}
} else if (!strcmp("creadreg", args[1].str)) {
uint8_t data[64];
uint8_t outdata;
int err;
size_t len = args[5].u;
if (argc < 6)
goto notenoughargs;
if (len == 0 || len > 64) {
puts("invalid len\n");
return -1;
}
outdata = args[4].u & 0xff;
err = iic_read(bus, addr, &outdata, 1, data, len, IIC_COMBINED);
if (err < 0) {
printf("error %d reading from iic\n", err);
} else {
hexdump(data, len);
}
} else if (!strcmp("readreg16", args[1].str)) {
uint8_t data[64];
uint16_t outdata;
int err;
size_t len = args[5].u;
if (argc < 6)
goto notenoughargs;
if (len == 0 || len > 64) {
puts("invalid len\n");
return -1;
}
outdata = swap16(args[4].u & 0xffff);
err = iic_read(bus, addr, &outdata, 2, data, len, IIC_NORMAL);
if (err < 0) {
printf("error %d reading from iic\n", err);
} else {
hexdump(data, len);
}
} else if (!strcmp("write", args[1].str)) {
u_int8_t data[64];
size_t len, i;
int err;
len = argc - 4;
if (len > sizeof(data)) len = sizeof(data);
for (i = 0; i < len; i++) {
data[i] = args[i+4].u;
}
printf("writing %zu bytes of data\n", len);
err = iic_write(bus, addr, data, len);
if (err < 0)
printf("error %d writing to iic\n", err);
} else if (!strcmp("probe", args[1].str)) {
for (addr = 1; addr < 0x7e; addr++) {
if (iic_probe(bus, addr))
printf("0x%02x: found\n", addr);
}
} else {
puts("unrecognized command.\n");
goto usage;
}
return 0;
}
MENU_COMMAND_DEVELOPMENT(iic, do_iic, "iic read/write", NULL);
#endif
+17
View File
@@ -0,0 +1,17 @@
# Copyright (C) 2008 Apple Computer, Inc. All rights reserved.
#
# This document is the property of Apple Computer, Inc.
# It is considered confidential and proprietary.
#
# This document may not be reproduced or transmitted in any form,
# in whole or in part, without the express written permission of
# Apple Computer, Inc.
#
LOCAL_DIR := $(GET_LOCAL_DIR)
OPTIONS += \
WITH_IIC=1
ALL_OBJS += \
$(LOCAL_DIR)/swiic.o \
$(LOCAL_DIR)/debug.o
+355
View File
@@ -0,0 +1,355 @@
/*
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* This document is the property of Apple Inc.
* It is considered confidential and proprietary.
*
* This document may not be reproduced or transmitted in any form,
* in whole or in part, without the express written permission of
* Apple Inc.
*/
/* if no hardware IIC, use the software fallback */
#if !WITH_HW_IIC
#include <debug.h>
#include <drivers/iic.h>
#include <platform.h>
#include <platform/gpio.h>
#include <platform/gpiodef.h>
#include <sys.h>
#include <sys/task.h>
#ifndef IICS_MASK
#define IICS_MASK ((1 << IICS_COUNT) - 1)
#endif
static struct iic_soft_device *get_iic_soft_device(int port);
static void iic_soft_setup(struct iic_soft_device *dev);
static void iic_soft_reset_bus(struct iic_soft_device *dev);
static void _setSCL(struct iic_soft_device *dev, bool assert);
static void _setSDA(struct iic_soft_device *dev, bool assert);
static u_int32_t _getSDA(struct iic_soft_device *dev);
static void _sendStart(struct iic_soft_device *dev);
static void _sendRestart(struct iic_soft_device *dev);
static void _sendStop(struct iic_soft_device *dev);
static void _sendAck(struct iic_soft_device *dev, bool ack);
static bool _writeByte(struct iic_soft_device *dev, u_int8_t data);
static u_int8_t _readByte(struct iic_soft_device *dev, bool ack);
/* struct definition */
struct iic_soft_device {
u_int32_t _i2cPeriod;
u_int32_t _i2cSlaveDevice;
u_int32_t iicAddressLength;
const u_int8_t *iicAddressBuffer;
u_int32_t iicDataLength;
u_int8_t *iicDataBuffer;
u_int32_t _i2cDelay;
u_int32_t _i2cSDA;
gpio_t gpio_scl;
gpio_t gpio_sda;
};
void iic_init(void)
{
int iic;
dprintf(DEBUG_INFO, "iic_soft_init()\n");
for (iic = 0; iic < IICS_COUNT; iic++)
iic_soft_setup(get_iic_soft_device(iic));
}
void iic_set_filter(int iic, uint32_t value) {}
void iic_set_frequency(int iic, u_int32_t frequency) {}
int iic_read(int iic, u_int8_t address, const void *send_data, size_t send_len, void *data, size_t len, iic_fmt_t fmt)
{
struct iic_soft_device *dev = get_iic_soft_device(iic);
u_int32_t cnt = 0;
if (dev == 0) return -1;
if (send_len == 0) return -1;
dev->_i2cSlaveDevice = address;
dev->iicAddressLength = send_len;
dev->iicAddressBuffer = (const u_int8_t *)send_data;
dev->iicDataLength = len;
dev->iicDataBuffer = (u_int8_t *)data;
/* Send slave address */
_sendStart(dev);
if (!_writeByte(dev, dev->_i2cSlaveDevice & ~(0x1))) {
_sendStop(dev);
return -1;
}
/* Send address bytes */
for (cnt = 0; cnt < dev->iicAddressLength; cnt++) {
if (!_writeByte(dev, dev->iicAddressBuffer[cnt])) {
_sendStop(dev);
return -1;
}
}
if (fmt == IIC_NORMAL) {
/* Stop */
_sendStop(dev);
_sendStart(dev);
} else {
_sendRestart(dev);
}
/* Send slave address */
if (!_writeByte(dev, dev->_i2cSlaveDevice | (0x1))) {
_sendStop(dev);
return -1;
}
/* clock data in */
for (cnt = 0; cnt < dev->iicDataLength; cnt++) {
dev->iicDataBuffer[cnt] = _readByte(dev, cnt < (dev->iicDataLength -1));
}
/* Stop */
_sendStop(dev);
return 0;
}
int iic_write(int iic, u_int8_t address, const void *data, size_t len)
{
struct iic_soft_device *dev = get_iic_soft_device(iic);
u_int32_t cnt =0;
if (dev == 0) return -1;
dev->_i2cSlaveDevice = address;
dev->iicAddressLength = 0;
dev->iicAddressBuffer = 0;
dev->iicDataLength = len;
dev->iicDataBuffer = (u_int8_t *)data;
/* Send slave address */
_sendStart(dev);
if (!_writeByte(dev, dev->_i2cSlaveDevice & ~(0x1))) {
_sendStop(dev);
return -1;
}
/* Send data bytes */
for (cnt = 0; cnt < dev->iicDataLength; cnt++) {
if (!_writeByte(dev, dev->iicDataBuffer[cnt])) {
_sendStop(dev);
return -1;
}
}
/* Send stop */
_sendStop(dev);
return 0;
}
bool iic_probe(int iic, u_int8_t address)
{
/* might be nice to implement this */
return false;
}
/* Private */
static struct iic_soft_device _iic_soft_device[] = {
#if IICS_COUNT > 0
{
.gpio_scl = GPIO_IIC0_SCL,
.gpio_sda = GPIO_IIC0_SDA,
},
#endif
#if IICS_COUNT > 1
{
.gpio_scl = GPIO_IIC1_SCL,
.gpio_sda = GPIO_IIC1_SDA,
},
#endif
#if IICS_COUNT > 2
{
.gpio_scl = GPIO_IIC2_SCL,
.gpio_sda = GPIO_IIC2_SDA,
}
#endif
};
static struct iic_soft_device *get_iic_soft_device(int port)
{
if (!((1 << port) & IICS_MASK))
return 0;
return &_iic_soft_device[port];
}
static void iic_soft_setup(struct iic_soft_device *dev)
{
if (dev == 0) return;
/* set the clock as 400kHz */
// dev->_i2cPeriod = 2500;
// dev->_i2cDelay = (dev->_i2cPeriod + 3)/4;
/*reset the bus */
iic_soft_reset_bus(dev);
}
static void iic_soft_reset_bus(struct iic_soft_device *dev)
{
u_int32_t cnt;
// Write 00 so all devices will complete any partial transaction
// SDA starts low and goes high after the loop
// SCL start and ends the loop high
// The first and last iterations of the loop produce the
// start and stop conditions
gpio_configure(dev->gpio_sda, GPIO_CFG_OUT_0);
for (cnt = 0; cnt < (2 * 9 + 1); cnt++) {
gpio_configure(dev->gpio_scl, (cnt & 1) ? GPIO_CFG_OUT_0 : GPIO_CFG_IN);
spin(5);
}
gpio_configure(dev->gpio_scl, GPIO_CFG_IN);
gpio_configure(dev->gpio_sda, GPIO_CFG_IN);
}
static void _setSCL(struct iic_soft_device *dev, bool assert)
{
if (assert) {
gpio_configure(dev->gpio_scl, GPIO_CFG_IN);
} else {
gpio_configure(dev->gpio_scl, GPIO_CFG_OUT_0);
}
}
static void _setSDA(struct iic_soft_device *dev, bool assert)
{
if (assert) {
gpio_configure(dev->gpio_sda, GPIO_CFG_IN);
} else {
gpio_configure(dev->gpio_sda, GPIO_CFG_OUT_0);
}
}
static u_int32_t _getSDA(struct iic_soft_device *dev)
{
u_int32_t tmp;
gpio_configure(dev->gpio_sda, GPIO_CFG_IN);
tmp = gpio_read(dev->gpio_sda);
return tmp;
}
/* Send Start: SDA High -> Low while SCL is high */
static void _sendStart(struct iic_soft_device *dev)
{
spin(1);
spin(1);
_setSDA(dev, false);
spin(1);
}
/* Send Restart: XXX */
static void _sendRestart(struct iic_soft_device *dev)
{
_setSCL(dev, false);
spin(1);
_setSDA(dev, true);
spin(1);
_setSCL(dev, true);
spin(1);
_setSDA(dev, false);
}
/* Send Stop: SDA Low -> High while SCL is high */
static void _sendStop(struct iic_soft_device *dev)
{
_setSCL(dev, false);
spin(1);
_setSDA(dev, false);
spin(1);
_setSCL(dev, true);
spin(1);
_setSDA(dev, true);
}
static void _sendAck(struct iic_soft_device *dev, bool ack)
{
_setSCL(dev, false);
spin(1);
_setSDA(dev, !ack);
spin(1);
_setSCL(dev, true);
spin(1);
spin(1);
}
static bool _writeByte(struct iic_soft_device *dev, u_int8_t data)
{
u_int32_t cnt;
u_int32_t ack;
/* Send the byte */
for (cnt = 0; cnt < 8; cnt++) {
_setSCL(dev, false);
spin(1);
_setSDA(dev, data & 0x80);
spin(1);
_setSCL(dev, true);
spin(1);
spin(1);
data = (data << 1);
}
/* Look for the ACK */
_setSCL(dev, false);
spin(1);
_setSDA(dev, true);
spin(1);
_setSCL(dev, true);
spin(1);
ack = !_getSDA(dev);
spin(1);
return (ack != 0);
}
static u_int8_t _readByte(struct iic_soft_device *dev, bool ack)
{
u_int32_t cnt;
u_int8_t data = 0;
for (cnt = 0; cnt < 8; cnt++) {
_setSCL(dev, false);
spin(1);
_setSDA(dev, true);
spin(1);
_setSCL(dev, true);
spin(1);
data <<= 1;
data |= _getSDA(dev);
spin(1);
}
_sendAck(dev, ack);
return data;
}
#endif /* !WITH_HW_IIC */