linux/include/media/cec.h
<<
>>
Prefs
   1/*
   2 * cec - HDMI Consumer Electronics Control support header
   3 *
   4 * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
   5 *
   6 * This program is free software; you may redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; version 2 of the License.
   9 *
  10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  17 * SOFTWARE.
  18 */
  19
  20#ifndef _MEDIA_CEC_H
  21#define _MEDIA_CEC_H
  22
  23#include <linux/poll.h>
  24#include <linux/fs.h>
  25#include <linux/debugfs.h>
  26#include <linux/device.h>
  27#include <linux/cdev.h>
  28#include <linux/kthread.h>
  29#include <linux/timer.h>
  30#include <linux/cec-funcs.h>
  31#include <media/rc-core.h>
  32#include <media/cec-edid.h>
  33
  34/**
  35 * struct cec_devnode - cec device node
  36 * @dev:        cec device
  37 * @cdev:       cec character device
  38 * @parent:     parent device
  39 * @minor:      device node minor number
  40 * @registered: the device was correctly registered
  41 * @unregistered: the device was unregistered
  42 * @fhs_lock:   lock to control access to the filehandle list
  43 * @fhs:        the list of open filehandles (cec_fh)
  44 *
  45 * This structure represents a cec-related device node.
  46 *
  47 * The @parent is a physical device. It must be set by core or device drivers
  48 * before registering the node.
  49 */
  50struct cec_devnode {
  51        /* sysfs */
  52        struct device dev;
  53        struct cdev cdev;
  54        struct device *parent;
  55
  56        /* device info */
  57        int minor;
  58        bool registered;
  59        bool unregistered;
  60        struct list_head fhs;
  61        struct mutex lock;
  62};
  63
  64struct cec_adapter;
  65struct cec_data;
  66
  67struct cec_data {
  68        struct list_head list;
  69        struct list_head xfer_list;
  70        struct cec_adapter *adap;
  71        struct cec_msg msg;
  72        struct cec_fh *fh;
  73        struct delayed_work work;
  74        struct completion c;
  75        u8 attempts;
  76        bool new_initiator;
  77        bool blocking;
  78        bool completed;
  79};
  80
  81struct cec_msg_entry {
  82        struct list_head        list;
  83        struct cec_msg          msg;
  84};
  85
  86#define CEC_NUM_EVENTS          CEC_EVENT_LOST_MSGS
  87
  88struct cec_fh {
  89        struct list_head        list;
  90        struct list_head        xfer_list;
  91        struct cec_adapter      *adap;
  92        u8                      mode_initiator;
  93        u8                      mode_follower;
  94
  95        /* Events */
  96        wait_queue_head_t       wait;
  97        unsigned int            pending_events;
  98        struct cec_event        events[CEC_NUM_EVENTS];
  99        struct mutex            lock;
 100        struct list_head        msgs; /* queued messages */
 101        unsigned int            queued_msgs;
 102};
 103
 104#define CEC_SIGNAL_FREE_TIME_RETRY              3
 105#define CEC_SIGNAL_FREE_TIME_NEW_INITIATOR      5
 106#define CEC_SIGNAL_FREE_TIME_NEXT_XFER          7
 107
 108/* The nominal data bit period is 2.4 ms */
 109#define CEC_FREE_TIME_TO_USEC(ft)               ((ft) * 2400)
 110
 111struct cec_adap_ops {
 112        /* Low-level callbacks */
 113        int (*adap_enable)(struct cec_adapter *adap, bool enable);
 114        int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable);
 115        int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr);
 116        int (*adap_transmit)(struct cec_adapter *adap, u8 attempts,
 117                             u32 signal_free_time, struct cec_msg *msg);
 118        void (*adap_status)(struct cec_adapter *adap, struct seq_file *file);
 119
 120        /* High-level CEC message callback */
 121        int (*received)(struct cec_adapter *adap, struct cec_msg *msg);
 122};
 123
 124/*
 125 * The minimum message length you can receive (excepting poll messages) is 2.
 126 * With a transfer rate of at most 36 bytes per second this makes 18 messages
 127 * per second worst case.
 128 *
 129 * We queue at most 3 seconds worth of received messages. The CEC specification
 130 * requires that messages are replied to within a second, so 3 seconds should
 131 * give more than enough margin. Since most messages are actually more than 2
 132 * bytes, this is in practice a lot more than 3 seconds.
 133 */
 134#define CEC_MAX_MSG_RX_QUEUE_SZ         (18 * 3)
 135
 136/*
 137 * The transmit queue is limited to 1 second worth of messages (worst case).
 138 * Messages can be transmitted by userspace and kernel space. But for both it
 139 * makes no sense to have a lot of messages queued up. One second seems
 140 * reasonable.
 141 */
 142#define CEC_MAX_MSG_TX_QUEUE_SZ         (18 * 1)
 143
 144struct cec_adapter {
 145        struct module *owner;
 146        char name[32];
 147        struct cec_devnode devnode;
 148        struct mutex lock;
 149        struct rc_dev *rc;
 150
 151        struct list_head transmit_queue;
 152        unsigned int transmit_queue_sz;
 153        struct list_head wait_queue;
 154        struct cec_data *transmitting;
 155
 156        struct task_struct *kthread_config;
 157        struct completion config_completion;
 158
 159        struct task_struct *kthread;
 160        wait_queue_head_t kthread_waitq;
 161        wait_queue_head_t waitq;
 162
 163        const struct cec_adap_ops *ops;
 164        void *priv;
 165        u32 capabilities;
 166        u8 available_log_addrs;
 167
 168        u16 phys_addr;
 169        bool is_configuring;
 170        bool is_configured;
 171        u32 monitor_all_cnt;
 172        u32 follower_cnt;
 173        struct cec_fh *cec_follower;
 174        struct cec_fh *cec_initiator;
 175        bool passthrough;
 176        struct cec_log_addrs log_addrs;
 177
 178        struct dentry *cec_dir;
 179        struct dentry *status_file;
 180
 181        u16 phys_addrs[15];
 182        u32 sequence;
 183
 184        char input_name[32];
 185        char input_phys[32];
 186        char input_drv[32];
 187};
 188
 189static inline bool cec_has_log_addr(const struct cec_adapter *adap, u8 log_addr)
 190{
 191        return adap->log_addrs.log_addr_mask & (1 << log_addr);
 192}
 193
 194static inline bool cec_is_sink(const struct cec_adapter *adap)
 195{
 196        return adap->phys_addr == 0;
 197}
 198
 199#if IS_ENABLED(CONFIG_MEDIA_CEC)
 200struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops,
 201                void *priv, const char *name, u32 caps, u8 available_las,
 202                struct device *parent);
 203int cec_register_adapter(struct cec_adapter *adap);
 204void cec_unregister_adapter(struct cec_adapter *adap);
 205void cec_delete_adapter(struct cec_adapter *adap);
 206
 207int cec_s_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs,
 208                    bool block);
 209void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
 210                     bool block);
 211int cec_transmit_msg(struct cec_adapter *adap, struct cec_msg *msg,
 212                     bool block);
 213
 214/* Called by the adapter */
 215void cec_transmit_done(struct cec_adapter *adap, u8 status, u8 arb_lost_cnt,
 216                       u8 nack_cnt, u8 low_drive_cnt, u8 error_cnt);
 217void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg);
 218
 219#else
 220
 221static inline int cec_register_adapter(struct cec_adapter *adap)
 222{
 223        return 0;
 224}
 225
 226static inline void cec_unregister_adapter(struct cec_adapter *adap)
 227{
 228}
 229
 230static inline void cec_delete_adapter(struct cec_adapter *adap)
 231{
 232}
 233
 234static inline void cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr,
 235                                   bool block)
 236{
 237}
 238
 239#endif
 240
 241#endif /* _MEDIA_CEC_H */
 242