From 74e8a71768c5b6ce04e45b4418784c70d6ca3386 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Wed, 9 Feb 2022 00:07:42 +0000 Subject: Move driver to core (#15944) --- drivers/gpio/mcp23018.c | 108 ++++++++++++++++++++++++++++++++++ drivers/gpio/mcp23018.h | 65 +++++++++++++++++++++ keyboards/viktus/sp111/mcp23018.c | 120 -------------------------------------- keyboards/viktus/sp111/mcp23018.h | 34 ----------- keyboards/viktus/sp111/rules.mk | 1 + 5 files changed, 174 insertions(+), 154 deletions(-) create mode 100644 drivers/gpio/mcp23018.c create mode 100644 drivers/gpio/mcp23018.h delete mode 100644 keyboards/viktus/sp111/mcp23018.c delete mode 100644 keyboards/viktus/sp111/mcp23018.h diff --git a/drivers/gpio/mcp23018.c b/drivers/gpio/mcp23018.c new file mode 100644 index 0000000000..dc8ab03c50 --- /dev/null +++ b/drivers/gpio/mcp23018.c @@ -0,0 +1,108 @@ +// Copyright 2022 zvecr +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "mcp23018.h" +#include "i2c_master.h" +#include "wait.h" +#include "debug.h" + +#define SLAVE_TO_ADDR(n) (n << 1) +#define TIMEOUT 100 + +enum { + CMD_IODIRA = 0x00, // i/o direction register + CMD_IODIRB = 0x01, + CMD_GPPUA = 0x0C, // GPIO pull-up resistor register + CMD_GPPUB = 0x0D, + CMD_GPIOA = 0x12, // general purpose i/o port register (write modifies OLAT) + CMD_GPIOB = 0x13, +}; + +void mcp23018_init(uint8_t addr) { + static uint8_t s_init = 0; + if (!s_init) { + i2c_init(); + wait_ms(1000); + + s_init = 1; + } +} + +bool mcp23018_set_config(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf) { + uint8_t addr = SLAVE_TO_ADDR(slave_addr); + uint8_t cmdDirection = port ? CMD_IODIRB : CMD_IODIRA; + uint8_t cmdPullup = port ? CMD_GPPUB : CMD_GPPUA; + + i2c_status_t ret = i2c_writeReg(addr, cmdDirection, &conf, sizeof(conf), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + dprintf("mcp23018_set_config::directionFAILED::%u\n", ret); + return false; + } + + ret = i2c_writeReg(addr, cmdPullup, &conf, sizeof(conf), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + dprintf("mcp23018_set_config::pullupFAILED::%u\n", ret); + return false; + } + + return true; +} + +bool mcp23018_set_output(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf) { + uint8_t addr = SLAVE_TO_ADDR(slave_addr); + uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA; + + i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + dprintf("mcp23018_set_output::FAILED::%u\n", ret); + return false; + } + + return true; +} + +bool mcp23018_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB) { + uint8_t addr = SLAVE_TO_ADDR(slave_addr); + uint8_t conf[2] = {confA, confB}; + + i2c_status_t ret = i2c_writeReg(addr, CMD_GPIOA, &conf[0], sizeof(conf), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + dprintf("mcp23018_set_output::FAILED::%u\n", ret); + return false; + } + + return true; +} + +bool mcp23018_readPins(uint8_t slave_addr, mcp23018_port_t port, uint8_t* out) { + uint8_t addr = SLAVE_TO_ADDR(slave_addr); + uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA; + + i2c_status_t ret = i2c_readReg(addr, cmd, out, sizeof(uint8_t), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + dprintf("mcp23018_readPins::FAILED::%u\n", ret); + return false; + } + + return true; +} + +bool mcp23018_readPins_all(uint8_t slave_addr, uint16_t* out) { + uint8_t addr = SLAVE_TO_ADDR(slave_addr); + + typedef union { + uint8_t u8[2]; + uint16_t u16; + } data16; + + data16 data = {.u16 = 0}; + + i2c_status_t ret = i2c_readReg(addr, CMD_GPIOA, &data.u8[0], sizeof(data), TIMEOUT); + if (ret != I2C_STATUS_SUCCESS) { + dprintf("mcp23018_readPins::FAILED::%u\n", ret); + return false; + } + + *out = data.u16; + return true; +} diff --git a/drivers/gpio/mcp23018.h b/drivers/gpio/mcp23018.h new file mode 100644 index 0000000000..e7c2730dd1 --- /dev/null +++ b/drivers/gpio/mcp23018.h @@ -0,0 +1,65 @@ +// Copyright 2022 zvecr +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +/** + * Port ID + */ +typedef enum { + mcp23018_PORTA, + mcp23018_PORTB, +} mcp23018_port_t; + +/** + * Helpers for set_config + */ +enum { + ALL_OUTPUT = 0, + ALL_INPUT = 0xFF, +}; + +/** + * Helpers for set_output + */ +enum { + ALL_LOW = 0, + ALL_HIGH = 0xFF, +}; + +/** + * Init expander and any other dependent drivers + */ +void mcp23018_init(uint8_t slave_addr); + +/** + * Configure input/output to a given port + */ +bool mcp23018_set_config(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf); + +/** + * Write high/low to a given port + */ +bool mcp23018_set_output(uint8_t slave_addr, mcp23018_port_t port, uint8_t conf); + +/** + * Write high/low to both ports sequentially + * + * - slightly faster than multiple set_output + */ +bool mcp23018_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB); + +/** + * Read state of a given port + */ +bool mcp23018_readPins(uint8_t slave_addr, mcp23018_port_t port, uint8_t* ret); + +/** + * Read state of both ports sequentially + * + * - slightly faster than multiple readPins + */ +bool mcp23018_readPins_all(uint8_t slave_addr, uint16_t* ret); diff --git a/keyboards/viktus/sp111/mcp23018.c b/keyboards/viktus/sp111/mcp23018.c deleted file mode 100644 index f1d8e568d2..0000000000 --- a/keyboards/viktus/sp111/mcp23018.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 zvecr - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "mcp23018.h" -#include "i2c_master.h" -#include "wait.h" -#include "debug.h" - -#define SLAVE_TO_ADDR(n) (n << 1) -#define TIMEOUT 100 - -enum { - CMD_IODIRA = 0x00, // i/o direction register - CMD_IODIRB = 0x01, - CMD_GPPUA = 0x0C, // GPIO pull-up resistor register - CMD_GPPUB = 0x0D, - CMD_GPIOA = 0x12, // general purpose i/o port register (write modifies OLAT) - CMD_GPIOB = 0x13, -}; - -void mcp23018_init(uint8_t addr) { - static uint8_t s_init = 0; - if (!s_init) { - i2c_init(); - wait_ms(1000); - - s_init = 1; - } -} - -bool mcp23018_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmdDirection = port ? CMD_IODIRB : CMD_IODIRA; - uint8_t cmdPullup = port ? CMD_GPPUB : CMD_GPPUA; - - i2c_status_t ret = i2c_writeReg(addr, cmdDirection, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - dprintf("mcp23018_set_config::directionFAILED::%u\n", ret); - return false; - } - - ret = i2c_writeReg(addr, cmdPullup, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - dprintf("mcp23018_set_config::pullupFAILED::%u\n", ret); - return false; - } - - return true; -} - -bool mcp23018_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA; - - i2c_status_t ret = i2c_writeReg(addr, cmd, &conf, sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - dprintf("mcp23018_set_output::FAILED::%u\n", ret); - return false; - } - - return true; -} - -bool mcp23018_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t conf[2] = {confA, confB}; - - i2c_status_t ret = i2c_writeReg(addr, CMD_GPIOA, &conf[0], sizeof(conf), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - dprintf("mcp23018_set_output::FAILED::%u\n", ret); - return false; - } - - return true; -} - -bool mcp23018_readPins(uint8_t slave_addr, uint8_t port, uint8_t* out) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - uint8_t cmd = port ? CMD_GPIOB : CMD_GPIOA; - - i2c_status_t ret = i2c_readReg(addr, cmd, out, sizeof(uint8_t), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - dprintf("mcp23018_readPins::FAILED::%u\n", ret); - return false; - } - - return true; -} - -bool mcp23018_readPins_all(uint8_t slave_addr, uint16_t* out) { - uint8_t addr = SLAVE_TO_ADDR(slave_addr); - - typedef union { - uint8_t u8[2]; - uint16_t u16; - } data16; - - data16 data = {.u16 = 0}; - - i2c_status_t ret = i2c_readReg(addr, CMD_GPIOA, &data.u8[0], sizeof(data), TIMEOUT); - if (ret != I2C_STATUS_SUCCESS) { - dprintf("mcp23018_readPins::FAILED::%u\n", ret); - return false; - } - - *out = data.u16; - return true; -} diff --git a/keyboards/viktus/sp111/mcp23018.h b/keyboards/viktus/sp111/mcp23018.h deleted file mode 100644 index dc2251b72f..0000000000 --- a/keyboards/viktus/sp111/mcp23018.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2020 zvecr - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#pragma once - -#include -#include - -#define mcp23018_PORTA 0 -#define mcp23018_PORTB 1 - -#define ALL_OUTPUT 0 -#define ALL_INPUT 0xFF -#define ALL_LOW 0 -#define ALL_HIGH 0xFF - -void mcp23018_init(uint8_t addr); -bool mcp23018_set_config(uint8_t slave_addr, uint8_t port, uint8_t conf); -bool mcp23018_set_output(uint8_t slave_addr, uint8_t port, uint8_t conf); -bool mcp23018_set_output_all(uint8_t slave_addr, uint8_t confA, uint8_t confB); -bool mcp23018_readPins(uint8_t slave_addraddr, uint8_t port, uint8_t* ret); -bool mcp23018_readPins_all(uint8_t slave_addr, uint16_t* ret); diff --git a/keyboards/viktus/sp111/rules.mk b/keyboards/viktus/sp111/rules.mk index b779ef4cb2..fab90d4a88 100644 --- a/keyboards/viktus/sp111/rules.mk +++ b/keyboards/viktus/sp111/rules.mk @@ -22,5 +22,6 @@ LTO_ENABLE = yes # Smaller (and slightly faster) firmware # custom matrix setup CUSTOM_MATRIX = lite +VPATH += drivers/gpio SRC += mcp23018.c matrix.c QUANTUM_LIB_SRC += i2c_master.c -- cgit v1.2.1