linux/include/linux/extcon.h
<<
>>
Prefs
   1/*
   2 *  External connector (extcon) class driver
   3 *
   4 * Copyright (C) 2015 Samsung Electronics
   5 * Author: Chanwoo Choi <cw00.choi@samsung.com>
   6 *
   7 * Copyright (C) 2012 Samsung Electronics
   8 * Author: Donggeun Kim <dg77.kim@samsung.com>
   9 * Author: MyungJoo Ham <myungjoo.ham@samsung.com>
  10 *
  11 * based on switch class driver
  12 * Copyright (C) 2008 Google, Inc.
  13 * Author: Mike Lockwood <lockwood@android.com>
  14 *
  15 * This software is licensed under the terms of the GNU General Public
  16 * License version 2, as published by the Free Software Foundation, and
  17 * may be copied, distributed, and modified under those terms.
  18 *
  19 * This program is distributed in the hope that it will be useful,
  20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 * GNU General Public License for more details.
  23 *
  24*/
  25
  26#ifndef __LINUX_EXTCON_H__
  27#define __LINUX_EXTCON_H__
  28
  29#include <linux/device.h>
  30
  31/*
  32 * Define the unique id of supported external connectors
  33 */
  34#define EXTCON_NONE             0
  35
  36/* USB external connector */
  37#define EXTCON_USB              1
  38#define EXTCON_USB_HOST         2
  39
  40/* Charging external connector */
  41#define EXTCON_CHG_USB_SDP      5       /* Standard Downstream Port */
  42#define EXTCON_CHG_USB_DCP      6       /* Dedicated Charging Port */
  43#define EXTCON_CHG_USB_CDP      7       /* Charging Downstream Port */
  44#define EXTCON_CHG_USB_ACA      8       /* Accessory Charger Adapter */
  45#define EXTCON_CHG_USB_FAST     9
  46#define EXTCON_CHG_USB_SLOW     10
  47
  48/* Jack external connector */
  49#define EXTCON_JACK_MICROPHONE  20
  50#define EXTCON_JACK_HEADPHONE   21
  51#define EXTCON_JACK_LINE_IN     22
  52#define EXTCON_JACK_LINE_OUT    23
  53#define EXTCON_JACK_VIDEO_IN    24
  54#define EXTCON_JACK_VIDEO_OUT   25
  55#define EXTCON_JACK_SPDIF_IN    26      /* Sony Philips Digital InterFace */
  56#define EXTCON_JACK_SPDIF_OUT   27
  57
  58/* Display external connector */
  59#define EXTCON_DISP_HDMI        40      /* High-Definition Multimedia Interface */
  60#define EXTCON_DISP_MHL         41      /* Mobile High-Definition Link */
  61#define EXTCON_DISP_DVI         42      /* Digital Visual Interface */
  62#define EXTCON_DISP_VGA         43      /* Video Graphics Array */
  63
  64/* Miscellaneous external connector */
  65#define EXTCON_DOCK             60
  66#define EXTCON_JIG              61
  67#define EXTCON_MECHANICAL       62
  68
  69#define EXTCON_NUM              63
  70
  71struct extcon_cable;
  72
  73/**
  74 * struct extcon_dev - An extcon device represents one external connector.
  75 * @name:               The name of this extcon device. Parent device name is
  76 *                      used if NULL.
  77 * @supported_cable:    Array of supported cable names ending with EXTCON_NONE.
  78 *                      If supported_cable is NULL, cable name related APIs
  79 *                      are disabled.
  80 * @mutually_exclusive: Array of mutually exclusive set of cables that cannot
  81 *                      be attached simultaneously. The array should be
  82 *                      ending with NULL or be NULL (no mutually exclusive
  83 *                      cables). For example, if it is { 0x7, 0x30, 0}, then,
  84 *                      {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot
  85 *                      be attached simulataneously. {0x7, 0} is equivalent to
  86 *                      {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there
  87 *                      can be no simultaneous connections.
  88 * @dev:                Device of this extcon.
  89 * @state:              Attach/detach state of this extcon. Do not provide at
  90 *                      register-time.
  91 * @nh:                 Notifier for the state change events from this extcon
  92 * @entry:              To support list of extcon devices so that users can
  93 *                      search for extcon devices based on the extcon name.
  94 * @lock:
  95 * @max_supported:      Internal value to store the number of cables.
  96 * @extcon_dev_type:    Device_type struct to provide attribute_groups
  97 *                      customized for each extcon device.
  98 * @cables:             Sysfs subdirectories. Each represents one cable.
  99 *
 100 * In most cases, users only need to provide "User initializing data" of
 101 * this struct when registering an extcon. In some exceptional cases,
 102 * optional callbacks may be needed. However, the values in "internal data"
 103 * are overwritten by register function.
 104 */
 105struct extcon_dev {
 106        /* Optional user initializing data */
 107        const char *name;
 108        const unsigned int *supported_cable;
 109        const u32 *mutually_exclusive;
 110
 111        /* Internal data. Please do not set. */
 112        struct device dev;
 113        struct raw_notifier_head *nh;
 114        struct list_head entry;
 115        int max_supported;
 116        spinlock_t lock;        /* could be called by irq handler */
 117        u32 state;
 118
 119        /* /sys/class/extcon/.../cable.n/... */
 120        struct device_type extcon_dev_type;
 121        struct extcon_cable *cables;
 122
 123        /* /sys/class/extcon/.../mutually_exclusive/... */
 124        struct attribute_group attr_g_muex;
 125        struct attribute **attrs_muex;
 126        struct device_attribute *d_attrs_muex;
 127};
 128
 129/**
 130 * struct extcon_cable - An internal data for each cable of extcon device.
 131 * @edev:               The extcon device
 132 * @cable_index:        Index of this cable in the edev
 133 * @attr_g:             Attribute group for the cable
 134 * @attr_name:          "name" sysfs entry
 135 * @attr_state:         "state" sysfs entry
 136 * @attrs:              Array pointing to attr_name and attr_state for attr_g
 137 */
 138struct extcon_cable {
 139        struct extcon_dev *edev;
 140        int cable_index;
 141
 142        struct attribute_group attr_g;
 143        struct device_attribute attr_name;
 144        struct device_attribute attr_state;
 145
 146        struct attribute *attrs[3]; /* to be fed to attr_g.attrs */
 147};
 148
 149/**
 150 * struct extcon_specific_cable_nb - An internal data for
 151 *                                   extcon_register_interest().
 152 * @user_nb:            user provided notifier block for events from
 153 *                      a specific cable.
 154 * @cable_index:        the target cable.
 155 * @edev:               the target extcon device.
 156 * @previous_value:     the saved previous event value.
 157 */
 158struct extcon_specific_cable_nb {
 159        struct notifier_block *user_nb;
 160        int cable_index;
 161        struct extcon_dev *edev;
 162        unsigned long previous_value;
 163};
 164
 165#if IS_ENABLED(CONFIG_EXTCON)
 166
 167/*
 168 * Following APIs are for notifiers or configurations.
 169 * Notifiers are the external port and connection devices.
 170 */
 171extern int extcon_dev_register(struct extcon_dev *edev);
 172extern void extcon_dev_unregister(struct extcon_dev *edev);
 173extern int devm_extcon_dev_register(struct device *dev,
 174                                    struct extcon_dev *edev);
 175extern void devm_extcon_dev_unregister(struct device *dev,
 176                                       struct extcon_dev *edev);
 177extern struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name);
 178
 179/*
 180 * Following APIs control the memory of extcon device.
 181 */
 182extern struct extcon_dev *extcon_dev_allocate(const unsigned int *cable);
 183extern void extcon_dev_free(struct extcon_dev *edev);
 184extern struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
 185                                                   const unsigned int *cable);
 186extern void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev);
 187
 188/*
 189 * get/set/update_state access the 32b encoded state value, which represents
 190 * states of all possible cables of the multistate port. For example, if one
 191 * calls extcon_set_state(edev, 0x7), it may mean that all the three cables
 192 * are attached to the port.
 193 */
 194static inline u32 extcon_get_state(struct extcon_dev *edev)
 195{
 196        return edev->state;
 197}
 198
 199extern int extcon_set_state(struct extcon_dev *edev, u32 state);
 200extern int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state);
 201
 202/*
 203 * get/set_cable_state access each bit of the 32b encoded state value.
 204 * They are used to access the status of each cable based on the cable_name.
 205 */
 206extern int extcon_get_cable_state_(struct extcon_dev *edev, unsigned int id);
 207extern int extcon_set_cable_state_(struct extcon_dev *edev, unsigned int id,
 208                                   bool cable_state);
 209
 210extern int extcon_get_cable_state(struct extcon_dev *edev,
 211                                  const char *cable_name);
 212extern int extcon_set_cable_state(struct extcon_dev *edev,
 213                                  const char *cable_name, bool cable_state);
 214
 215/*
 216 * Following APIs are for notifiees (those who want to be notified)
 217 * to register a callback for events from a specific cable of the extcon.
 218 * Notifiees are the connected device drivers wanting to get notified by
 219 * a specific external port of a connection device.
 220 */
 221extern int extcon_register_interest(struct extcon_specific_cable_nb *obj,
 222                                    const char *extcon_name,
 223                                    const char *cable_name,
 224                                    struct notifier_block *nb);
 225extern int extcon_unregister_interest(struct extcon_specific_cable_nb *nb);
 226
 227/*
 228 * Following APIs are to monitor every action of a notifier.
 229 * Registrar gets notified for every external port of a connection device.
 230 * Probably this could be used to debug an action of notifier; however,
 231 * we do not recommend to use this for normal 'notifiee' device drivers who
 232 * want to be notified by a specific external port of the notifier.
 233 */
 234extern int extcon_register_notifier(struct extcon_dev *edev, unsigned int id,
 235                                    struct notifier_block *nb);
 236extern int extcon_unregister_notifier(struct extcon_dev *edev, unsigned int id,
 237                                    struct notifier_block *nb);
 238
 239/*
 240 * Following API get the extcon device from devicetree.
 241 * This function use phandle of devicetree to get extcon device directly.
 242 */
 243extern struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
 244                                                     int index);
 245
 246/* Following API to get information of extcon device */
 247extern const char *extcon_get_edev_name(struct extcon_dev *edev);
 248
 249#else /* CONFIG_EXTCON */
 250static inline int extcon_dev_register(struct extcon_dev *edev)
 251{
 252        return 0;
 253}
 254
 255static inline void extcon_dev_unregister(struct extcon_dev *edev) { }
 256
 257static inline int devm_extcon_dev_register(struct device *dev,
 258                                           struct extcon_dev *edev)
 259{
 260        return -EINVAL;
 261}
 262
 263static inline void devm_extcon_dev_unregister(struct device *dev,
 264                                              struct extcon_dev *edev) { }
 265
 266static inline struct extcon_dev *extcon_dev_allocate(const unsigned int *cable)
 267{
 268        return ERR_PTR(-ENOSYS);
 269}
 270
 271static inline void extcon_dev_free(struct extcon_dev *edev) { }
 272
 273static inline struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
 274                                                const unsigned int *cable)
 275{
 276        return ERR_PTR(-ENOSYS);
 277}
 278
 279static inline void devm_extcon_dev_free(struct extcon_dev *edev) { }
 280
 281static inline u32 extcon_get_state(struct extcon_dev *edev)
 282{
 283        return 0;
 284}
 285
 286static inline int extcon_set_state(struct extcon_dev *edev, u32 state)
 287{
 288        return 0;
 289}
 290
 291static inline int extcon_update_state(struct extcon_dev *edev, u32 mask,
 292                                       u32 state)
 293{
 294        return 0;
 295}
 296
 297static inline int extcon_get_cable_state_(struct extcon_dev *edev,
 298                                          unsigned int id)
 299{
 300        return 0;
 301}
 302
 303static inline int extcon_set_cable_state_(struct extcon_dev *edev,
 304                                          unsigned int id, bool cable_state)
 305{
 306        return 0;
 307}
 308
 309static inline int extcon_get_cable_state(struct extcon_dev *edev,
 310                        const char *cable_name)
 311{
 312        return 0;
 313}
 314
 315static inline int extcon_set_cable_state(struct extcon_dev *edev,
 316                        const char *cable_name, int state)
 317{
 318        return 0;
 319}
 320
 321static inline struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
 322{
 323        return NULL;
 324}
 325
 326static inline int extcon_register_notifier(struct extcon_dev *edev,
 327                                        unsigned int id,
 328                                        struct notifier_block *nb)
 329{
 330        return 0;
 331}
 332
 333static inline int extcon_unregister_notifier(struct extcon_dev *edev,
 334                                        unsigned int id,
 335                                        struct notifier_block *nb)
 336{
 337        return 0;
 338}
 339
 340static inline int extcon_register_interest(struct extcon_specific_cable_nb *obj,
 341                                           const char *extcon_name,
 342                                           const char *cable_name,
 343                                           struct notifier_block *nb)
 344{
 345        return 0;
 346}
 347
 348static inline int extcon_unregister_interest(struct extcon_specific_cable_nb
 349                                                    *obj)
 350{
 351        return 0;
 352}
 353
 354static inline struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev,
 355                                                            int index)
 356{
 357        return ERR_PTR(-ENODEV);
 358}
 359#endif /* CONFIG_EXTCON */
 360#endif /* __LINUX_EXTCON_H__ */
 361