linux/drivers/pcmcia/socket_sysfs.c
<<
>>
Prefs
   1/*
   2 * socket_sysfs.c -- most of socket-related sysfs output
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 *
   8 * (C) 2003 - 2004              Dominik Brodowski
   9 */
  10
  11#include <linux/module.h>
  12#include <linux/moduleparam.h>
  13#include <linux/init.h>
  14#include <linux/kernel.h>
  15#include <linux/string.h>
  16#include <linux/major.h>
  17#include <linux/errno.h>
  18#include <linux/mm.h>
  19#include <linux/interrupt.h>
  20#include <linux/timer.h>
  21#include <linux/ioport.h>
  22#include <linux/delay.h>
  23#include <linux/pm.h>
  24#include <linux/device.h>
  25#include <linux/mutex.h>
  26#include <asm/system.h>
  27#include <asm/irq.h>
  28
  29#include <pcmcia/ss.h>
  30#include <pcmcia/cistpl.h>
  31#include <pcmcia/cisreg.h>
  32#include <pcmcia/ds.h>
  33#include "cs_internal.h"
  34
  35#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
  36
  37static ssize_t pccard_show_type(struct device *dev, struct device_attribute *attr,
  38                                char *buf)
  39{
  40        struct pcmcia_socket *s = to_socket(dev);
  41
  42        if (!(s->state & SOCKET_PRESENT))
  43                return -ENODEV;
  44        if (s->state & SOCKET_CARDBUS)
  45                return sprintf(buf, "32-bit\n");
  46        return sprintf(buf, "16-bit\n");
  47}
  48static DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
  49
  50static ssize_t pccard_show_voltage(struct device *dev, struct device_attribute *attr,
  51                                   char *buf)
  52{
  53        struct pcmcia_socket *s = to_socket(dev);
  54
  55        if (!(s->state & SOCKET_PRESENT))
  56                return -ENODEV;
  57        if (s->socket.Vcc)
  58                return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10,
  59                               s->socket.Vcc % 10);
  60        return sprintf(buf, "X.XV\n");
  61}
  62static DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
  63
  64static ssize_t pccard_show_vpp(struct device *dev, struct device_attribute *attr,
  65                               char *buf)
  66{
  67        struct pcmcia_socket *s = to_socket(dev);
  68        if (!(s->state & SOCKET_PRESENT))
  69                return -ENODEV;
  70        return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);
  71}
  72static DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
  73
  74static ssize_t pccard_show_vcc(struct device *dev, struct device_attribute *attr,
  75                               char *buf)
  76{
  77        struct pcmcia_socket *s = to_socket(dev);
  78        if (!(s->state & SOCKET_PRESENT))
  79                return -ENODEV;
  80        return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);
  81}
  82static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
  83
  84
  85static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr,
  86                                   const char *buf, size_t count)
  87{
  88        struct pcmcia_socket *s = to_socket(dev);
  89
  90        if (!count)
  91                return -EINVAL;
  92
  93        pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
  94
  95        return count;
  96}
  97static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
  98
  99
 100static ssize_t pccard_show_card_pm_state(struct device *dev,
 101                                         struct device_attribute *attr,
 102                                         char *buf)
 103{
 104        struct pcmcia_socket *s = to_socket(dev);
 105        return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on");
 106}
 107
 108static ssize_t pccard_store_card_pm_state(struct device *dev,
 109                                          struct device_attribute *attr,
 110                                          const char *buf, size_t count)
 111{
 112        struct pcmcia_socket *s = to_socket(dev);
 113        ssize_t ret = count;
 114
 115        if (!count)
 116                return -EINVAL;
 117
 118        if (!strncmp(buf, "off", 3))
 119                pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
 120        else {
 121                if (!strncmp(buf, "on", 2))
 122                        pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
 123                else
 124                        ret = -EINVAL;
 125        }
 126
 127        return ret;
 128}
 129static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
 130
 131static ssize_t pccard_store_eject(struct device *dev,
 132                                  struct device_attribute *attr,
 133                                  const char *buf, size_t count)
 134{
 135        struct pcmcia_socket *s = to_socket(dev);
 136
 137        if (!count)
 138                return -EINVAL;
 139
 140        pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
 141
 142        return count;
 143}
 144static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
 145
 146
 147static ssize_t pccard_show_irq_mask(struct device *dev,
 148                                    struct device_attribute *attr,
 149                                    char *buf)
 150{
 151        struct pcmcia_socket *s = to_socket(dev);
 152        return sprintf(buf, "0x%04x\n", s->irq_mask);
 153}
 154
 155static ssize_t pccard_store_irq_mask(struct device *dev,
 156                                     struct device_attribute *attr,
 157                                     const char *buf, size_t count)
 158{
 159        ssize_t ret;
 160        struct pcmcia_socket *s = to_socket(dev);
 161        u32 mask;
 162
 163        if (!count)
 164                return -EINVAL;
 165
 166        ret = sscanf(buf, "0x%x\n", &mask);
 167
 168        if (ret == 1) {
 169                mutex_lock(&s->ops_mutex);
 170                s->irq_mask &= mask;
 171                mutex_unlock(&s->ops_mutex);
 172                ret = 0;
 173        }
 174
 175        return ret ? ret : count;
 176}
 177static DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
 178
 179
 180static ssize_t pccard_show_resource(struct device *dev,
 181                                    struct device_attribute *attr, char *buf)
 182{
 183        struct pcmcia_socket *s = to_socket(dev);
 184        return sprintf(buf, "%s\n", s->resource_setup_done ? "yes" : "no");
 185}
 186
 187static ssize_t pccard_store_resource(struct device *dev,
 188                                     struct device_attribute *attr,
 189                                     const char *buf, size_t count)
 190{
 191        struct pcmcia_socket *s = to_socket(dev);
 192
 193        if (!count)
 194                return -EINVAL;
 195
 196        mutex_lock(&s->ops_mutex);
 197        if (!s->resource_setup_done)
 198                s->resource_setup_done = 1;
 199        mutex_unlock(&s->ops_mutex);
 200
 201        pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY);
 202
 203        return count;
 204}
 205static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
 206
 207static struct attribute *pccard_socket_attributes[] = {
 208        &dev_attr_card_type.attr,
 209        &dev_attr_card_voltage.attr,
 210        &dev_attr_card_vpp.attr,
 211        &dev_attr_card_vcc.attr,
 212        &dev_attr_card_insert.attr,
 213        &dev_attr_card_pm_state.attr,
 214        &dev_attr_card_eject.attr,
 215        &dev_attr_card_irq_mask.attr,
 216        &dev_attr_available_resources_setup_done.attr,
 217        NULL,
 218};
 219
 220static const struct attribute_group socket_attrs = {
 221        .attrs = pccard_socket_attributes,
 222};
 223
 224int pccard_sysfs_add_socket(struct device *dev)
 225{
 226        return sysfs_create_group(&dev->kobj, &socket_attrs);
 227}
 228
 229void pccard_sysfs_remove_socket(struct device *dev)
 230{
 231        sysfs_remove_group(&dev->kobj, &socket_attrs);
 232}
 233