From a2dad96ab736f66ed54421cad53caf31f250e181 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 23 Apr 2018 09:45:28 +0200 Subject: bsps: Move I2C drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libbsp/m68k/mcf5206elite/i2c/i2cdrv.c | 262 ------------------------ 1 file changed, 262 deletions(-) delete mode 100644 c/src/lib/libbsp/m68k/mcf5206elite/i2c/i2cdrv.c (limited to 'c/src/lib/libbsp/m68k/mcf5206elite/i2c/i2cdrv.c') diff --git a/c/src/lib/libbsp/m68k/mcf5206elite/i2c/i2cdrv.c b/c/src/lib/libbsp/m68k/mcf5206elite/i2c/i2cdrv.c deleted file mode 100644 index 838b0b26b1..0000000000 --- a/c/src/lib/libbsp/m68k/mcf5206elite/i2c/i2cdrv.c +++ /dev/null @@ -1,262 +0,0 @@ -/* I2C driver for MCF5206eLITE board. I2C bus accessed through on-chip - * MCF5206e MBUS controller. - * - * The purpose of this module is to perform I2C driver initialization - * and serialize I2C transfers. - * - * Copyright (C) 2000 OKTET Ltd., St.-Petersburg, Russia - * Author: Victor V. Vengerov - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * - * http://www.rtems.org/license/LICENSE. - */ - -#include -#include -#include -#include - -#include "i2c.h" -#include "i2cdrv.h" -#include "mcf5206/mcfmbus.h" - -#ifndef I2C_NUMBER_OF_BUSES -#define I2C_NUMBER_OF_BUSES (1) -#endif - -#ifndef I2C_SELECT_BUS -#define I2C_SELECT_BUS(bus) -#endif - -/* - * Few I2C transfers may be posted simultaneously, but MBUS driver is able - * to process it one-by-one. To serialize transfers, function i2c_transfer - * put transfer information to the queue and initiate new transfers if MBUS - * driver is not busy. When driver is busy, next transfer is dequeued - * when current active transfer is finished. - */ - -/* - * i2c_qel - I2C transfers queue element; contain information about - * delayed transfer - */ -typedef struct i2c_qel { - i2c_bus_number bus; /* I2C bus number */ - i2c_message *msg; /* pointer to the transfer' messages array */ - int nmsg; /* number of messages in transfer */ - i2c_transfer_done done; /* transfer done callback function */ - void * done_arg_ptr; /* arbitrary arg pointer to done callback */ -} i2c_qel; - -/* Memory for I2C transfer queue. This queue represented like a ring buffer */ -static i2c_qel *tqueue; - -/* Maximum number of elements in transfer queue */ -static int tqueue_size; - -/* Position of next free element in a ring buffer */ -static volatile int tqueue_head; - -/* Position of the first element in transfer queue */ -static volatile int tqueue_tail; - -/* MBus I2C bus controller busy flag */ -static volatile bool mbus_busy; - -/* MBus I2C bus controller descriptor */ -static mcfmbus mbus; - -/* Clock rate selected for each of bus */ -static int i2cdrv_bus_clock_div[I2C_NUMBER_OF_BUSES]; - -/* Currently selected I2C bus clock rate */ -static int i2cdrv_bus_clock_div_current; - -/* Forward function declaration */ -static void i2cdrv_unload(void); - -/* i2cdrv_done -- - * Callback function which is called from MBus low-level driver when - * transfer is finished. - */ -static void -i2cdrv_done(void * arg_ptr) -{ - rtems_interrupt_level level; - i2c_qel *qel = tqueue + tqueue_tail; - qel->done(qel->done_arg_ptr); - rtems_interrupt_disable(level); - tqueue_tail = (tqueue_tail + 1) % tqueue_size; - mbus_busy = false; - rtems_interrupt_enable(level); - i2cdrv_unload(); -} - -/* i2cdrv_unload -- - * If MBUS controller is not busy and transfer waiting in a queue, - * initiate processing of the next transfer in queue. - */ -static void -i2cdrv_unload(void) -{ - rtems_interrupt_level level; - i2c_qel *qel; - rtems_status_code sc; - rtems_interrupt_disable(level); - if (!mbus_busy && (tqueue_head != tqueue_tail)) - { - mbus_busy = true; - rtems_interrupt_enable(level); - qel = tqueue + tqueue_tail; - - I2C_SELECT_BUS(qel->bus); - if (i2cdrv_bus_clock_div[qel->bus] != i2cdrv_bus_clock_div_current) - { - i2cdrv_bus_clock_div_current = i2cdrv_bus_clock_div[qel->bus]; - mcfmbus_select_clock_divider(&mbus, i2cdrv_bus_clock_div_current); - } - sc = mcfmbus_i2c_transfer(&mbus, qel->nmsg, qel->msg, - i2cdrv_done,qel); - if (sc != RTEMS_SUCCESSFUL) - { - int i; - for (i = 0; i < qel->nmsg; i++) - { - qel->msg[i].status = I2C_RESOURCE_NOT_AVAILABLE; - } - i2cdrv_done(qel); - } - } - else - { - rtems_interrupt_enable(level); - } -} - -/* i2c_transfer -- - * Initiate multiple-messages transfer over specified I2C bus or - * put request into queue if bus or some other resource is busy. (This - * is non-blocking function). - * - * PARAMETERS: - * bus - I2C bus number - * nmsg - number of messages - * msg - pointer to messages array - * done - function which is called when transfer is finished - * done_arg_ptr - arbitrary argument pointer passed to done funciton - * - * RETURNS: - * RTEMS_SUCCESSFUL if transfer initiated successfully, or error - * code if something failed. - */ -rtems_status_code -i2c_transfer(i2c_bus_number bus, int nmsg, i2c_message *msg, - i2c_transfer_done done, void * done_arg_ptr) -{ - i2c_qel qel; - rtems_interrupt_level level; - - if (bus >= I2C_NUMBER_OF_BUSES) - { - return RTEMS_INVALID_NUMBER; - } - - if (msg == NULL) - { - return RTEMS_INVALID_ADDRESS; - } - - qel.bus = bus; - qel.msg = msg; - qel.nmsg = nmsg; - qel.done = done; - qel.done_arg_ptr = done_arg_ptr; - rtems_interrupt_disable(level); - if ((tqueue_head + 1) % tqueue_size == tqueue_tail) - { - rtems_interrupt_enable(level); - return RTEMS_TOO_MANY; - } - memcpy(tqueue + tqueue_head, &qel, sizeof(qel)); - tqueue_head = (tqueue_head + 1) % tqueue_size; - rtems_interrupt_enable(level); - i2cdrv_unload(); - return RTEMS_SUCCESSFUL; -} - -/* i2cdrv_initialize -- - * I2C driver initialization (rtems I/O driver primitive) - */ -rtems_device_driver -i2cdrv_initialize(rtems_device_major_number major, - rtems_device_minor_number minor, - void *arg) -{ - int i; - rtems_status_code sc; - mbus_busy = false; - tqueue_tail = tqueue_head = 0; - tqueue_size = 32; - tqueue = calloc(tqueue_size, sizeof(i2c_qel)); - - sc = mcfmbus_initialize(&mbus, MBAR); - if (sc != RTEMS_SUCCESSFUL) - return sc; - - for (i = 0; i < I2C_NUMBER_OF_BUSES; i++) - { - sc = i2c_select_clock_rate(i, 4096); - if (sc != RTEMS_SUCCESSFUL) - return sc; - } - i2cdrv_bus_clock_div_current = -1; - return RTEMS_SUCCESSFUL; -} - -/* i2c_select_clock_rate -- - * select I2C bus clock rate for specified bus. Some bus controller do not - * allow to select arbitrary clock rate; in this case nearest possible - * slower clock rate is selected. - * - * PARAMETERS: - * bus - I2C bus number - * bps - data transfer rate for this bytes in bits per second - * - * RETURNS: - * RTEMS_SUCCESSFUL, if operation performed successfully, - * RTEMS_INVALID_NUMBER, if wrong bus number is specified, - * RTEMS_UNSATISFIED, if bus do not support data transfer rate selection - * or specified data transfer rate could not be used. - */ -rtems_status_code -i2c_select_clock_rate(i2c_bus_number bus, int bps) -{ - int div; - if (bus >= I2C_NUMBER_OF_BUSES) - return RTEMS_INVALID_NUMBER; - - if (bps == 0) - return RTEMS_UNSATISFIED; - - div = BSP_SYSTEM_FREQUENCY / bps; - i2cdrv_bus_clock_div[bus] = div; - return RTEMS_SUCCESSFUL; -} - -/* i2c_poll -- - * Poll I2C bus controller for events and hanle it. This function is - * used when I2C driver operates in poll-driven mode. - * - * PARAMETERS: - * bus - bus number to be polled - * - * RETURNS: - * none - */ -void -i2c_poll(i2c_bus_number bus) -{ - mcfmbus_poll(&mbus); -} -- cgit v1.2.3