linux/drivers/staging/meilhaus/me0600_optoi.c
<<
>>
Prefs
   1/**
   2 * @file me0600_optoi.c
   3 *
   4 * @brief ME-630 Optoisolated input subdevice instance.
   5 * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
   6 * @author Guenter Gebhardt
   7 * @author Krzysztof Gantzke    (k.gantzke@meilhaus.de)
   8 */
   9
  10/*
  11 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
  12 *
  13 * This file is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License as published by
  15 * the Free Software Foundation; either version 2 of the License, or
  16 * (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26 */
  27
  28#ifndef __KERNEL__
  29#  define __KERNEL__
  30#endif
  31
  32/*
  33 * Includes
  34 */
  35#include <linux/module.h>
  36
  37#include <linux/slab.h>
  38#include <linux/spinlock.h>
  39#include <asm/io.h>
  40#include <linux/types.h>
  41
  42#include "medefines.h"
  43#include "meinternal.h"
  44#include "meerror.h"
  45
  46#include "medebug.h"
  47#include "me0600_optoi_reg.h"
  48#include "me0600_optoi.h"
  49
  50/*
  51 * Defines
  52 */
  53
  54/*
  55 * Functions
  56 */
  57
  58static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
  59                                           struct file *filep, int flags)
  60{
  61
  62        if (flags) {
  63                PERROR("Invalid flag specified.\n");
  64                return ME_ERRNO_INVALID_FLAGS;
  65        }
  66
  67        PDEBUG("executed.\n");
  68        return ME_ERRNO_SUCCESS;
  69}
  70
  71static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
  72                                         struct file *filep,
  73                                         int channel,
  74                                         int single_config,
  75                                         int ref,
  76                                         int trig_chan,
  77                                         int trig_type,
  78                                         int trig_edge, int flags)
  79{
  80        me0600_optoi_subdevice_t *instance;
  81        int err = ME_ERRNO_SUCCESS;
  82
  83        PDEBUG("executed.\n");
  84
  85        instance = (me0600_optoi_subdevice_t *) subdevice;
  86
  87        ME_SUBDEVICE_ENTER;
  88
  89        spin_lock(&instance->subdevice_lock);
  90
  91        switch (flags) {
  92        case ME_IO_SINGLE_CONFIG_NO_FLAGS:
  93        case ME_IO_SINGLE_CONFIG_DIO_BYTE:
  94                if (channel == 0) {
  95                        if (single_config != ME_SINGLE_CONFIG_DIO_INPUT) {
  96                                PERROR("Invalid port direction specified.\n");
  97                                err = ME_ERRNO_INVALID_SINGLE_CONFIG;
  98                        }
  99                } else {
 100                        PERROR("Invalid channel specified.\n");
 101                        err = ME_ERRNO_INVALID_CHANNEL;
 102                }
 103
 104                break;
 105
 106        default:
 107                PERROR("Invalid flags specified.\n");
 108
 109                err = ME_ERRNO_INVALID_FLAGS;
 110
 111                break;
 112        }
 113
 114        spin_unlock(&instance->subdevice_lock);
 115
 116        ME_SUBDEVICE_EXIT;
 117
 118        return err;
 119}
 120
 121static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
 122                                       struct file *filep,
 123                                       int channel,
 124                                       int *value, int time_out, int flags)
 125{
 126        me0600_optoi_subdevice_t *instance;
 127        int err = ME_ERRNO_SUCCESS;
 128
 129        PDEBUG("executed.\n");
 130
 131        instance = (me0600_optoi_subdevice_t *) subdevice;
 132
 133        ME_SUBDEVICE_ENTER;
 134
 135        spin_lock(&instance->subdevice_lock);
 136
 137        switch (flags) {
 138        case ME_IO_SINGLE_TYPE_DIO_BIT:
 139                if ((channel >= 0) && (channel < 8)) {
 140                        *value = inb(instance->port_reg) & (0x1 << channel);
 141                } else {
 142                        PERROR("Invalid bit number specified.\n");
 143                        err = ME_ERRNO_INVALID_CHANNEL;
 144                }
 145
 146                break;
 147
 148        case ME_IO_SINGLE_NO_FLAGS:
 149        case ME_IO_SINGLE_TYPE_DIO_BYTE:
 150                if (channel == 0) {
 151                        *value = inb(instance->port_reg);
 152                } else {
 153                        PERROR("Invalid byte number specified.\n");
 154                        err = ME_ERRNO_INVALID_CHANNEL;
 155                }
 156
 157                break;
 158
 159        default:
 160                PERROR("Invalid flags specified.\n");
 161
 162                err = ME_ERRNO_INVALID_FLAGS;
 163        }
 164
 165        spin_unlock(&instance->subdevice_lock);
 166
 167        ME_SUBDEVICE_EXIT;
 168
 169        return err;
 170}
 171
 172static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
 173                                              int *number)
 174{
 175        PDEBUG("executed.\n");
 176        *number = 8;
 177        return ME_ERRNO_SUCCESS;
 178}
 179
 180static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
 181                                             int *type, int *subtype)
 182{
 183        PDEBUG("executed.\n");
 184        *type = ME_TYPE_DI;
 185        *subtype = ME_SUBTYPE_SINGLE;
 186        return ME_ERRNO_SUCCESS;
 187}
 188
 189static int me0600_optoi_query_subdevice_caps(me_subdevice_t * subdevice,
 190                                             int *caps)
 191{
 192        PDEBUG("executed.\n");
 193        *caps = 0;
 194        return ME_ERRNO_SUCCESS;
 195}
 196
 197me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
 198{
 199        me0600_optoi_subdevice_t *subdevice;
 200        int err;
 201
 202        PDEBUG("executed.\n");
 203
 204        /* Allocate memory for subdevice instance */
 205        subdevice = kmalloc(sizeof(me0600_optoi_subdevice_t), GFP_KERNEL);
 206
 207        if (!subdevice) {
 208                PERROR("Cannot get memory for subdevice instance.\n");
 209                return NULL;
 210        }
 211
 212        memset(subdevice, 0, sizeof(me0600_optoi_subdevice_t));
 213
 214        /* Initialize subdevice base class */
 215        err = me_subdevice_init(&subdevice->base);
 216
 217        if (err) {
 218                PERROR("Cannot initialize subdevice base class instance.\n");
 219                kfree(subdevice);
 220                return NULL;
 221        }
 222        // Initialize spin locks.
 223        spin_lock_init(&subdevice->subdevice_lock);
 224
 225        /* Save the subdevice index */
 226        subdevice->port_reg = reg_base + ME0600_OPTO_INPUT_REG;
 227
 228        /* Overload base class methods. */
 229        subdevice->base.me_subdevice_io_reset_subdevice =
 230            me0600_optoi_io_reset_subdevice;
 231        subdevice->base.me_subdevice_io_single_config =
 232            me0600_optoi_io_single_config;
 233        subdevice->base.me_subdevice_io_single_read =
 234            me0600_optoi_io_single_read;
 235        subdevice->base.me_subdevice_query_number_channels =
 236            me0600_optoi_query_number_channels;
 237        subdevice->base.me_subdevice_query_subdevice_type =
 238            me0600_optoi_query_subdevice_type;
 239        subdevice->base.me_subdevice_query_subdevice_caps =
 240            me0600_optoi_query_subdevice_caps;
 241
 242        return subdevice;
 243}
 244
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.