Ezequiel Garcia | 704a84c | 2016-03-02 11:30:16 -0300 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar |
| 3 | * |
| 4 | * Copyright (C) 2015 Industrial Research Institute for Automation |
| 5 | * and Measurements PIAP |
| 6 | * Written by Krzysztof Ha?asa |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it |
| 9 | * under the terms of version 2 of the GNU General Public License |
| 10 | * as published by the Free Software Foundation. |
| 11 | */ |
| 12 | |
| 13 | #include <linux/mutex.h> |
| 14 | #include <linux/pci.h> |
| 15 | #include <linux/timer.h> |
| 16 | #include <linux/videodev2.h> |
| 17 | #include <media/v4l2-common.h> |
| 18 | #include <media/v4l2-ctrls.h> |
| 19 | #include <media/v4l2-device.h> |
| 20 | #include <media/v4l2-ioctl.h> |
| 21 | #include <media/videobuf2-v4l2.h> |
| 22 | #include <sound/pcm.h> |
| 23 | |
| 24 | #include "tw686x-regs.h" |
| 25 | |
| 26 | #define TYPE_MAX_CHANNELS 0x0f |
| 27 | #define TYPE_SECOND_GEN 0x10 |
| 28 | #define TW686X_DEF_PHASE_REF 0x1518 |
| 29 | |
| 30 | #define TW686X_FIELD_MODE 0x3 |
| 31 | #define TW686X_FRAME_MODE 0x2 |
| 32 | /* 0x1 is reserved */ |
| 33 | #define TW686X_SG_MODE 0x0 |
| 34 | |
| 35 | #define TW686X_AUDIO_PAGE_SZ 4096 |
| 36 | #define TW686X_AUDIO_PAGE_MAX 16 |
| 37 | #define TW686X_AUDIO_PERIODS_MIN 2 |
| 38 | #define TW686X_AUDIO_PERIODS_MAX TW686X_AUDIO_PAGE_MAX |
| 39 | |
| 40 | struct tw686x_format { |
| 41 | char *name; |
| 42 | unsigned int fourcc; |
| 43 | unsigned int depth; |
| 44 | unsigned int mode; |
| 45 | }; |
| 46 | |
| 47 | struct tw686x_dma_desc { |
| 48 | dma_addr_t phys; |
| 49 | void *virt; |
| 50 | unsigned int size; |
| 51 | }; |
| 52 | |
| 53 | struct tw686x_audio_buf { |
| 54 | dma_addr_t dma; |
| 55 | void *virt; |
| 56 | struct list_head list; |
| 57 | }; |
| 58 | |
| 59 | struct tw686x_v4l2_buf { |
| 60 | struct vb2_v4l2_buffer vb; |
| 61 | struct list_head list; |
| 62 | }; |
| 63 | |
| 64 | struct tw686x_audio_channel { |
| 65 | struct tw686x_dev *dev; |
| 66 | struct snd_pcm_substream *ss; |
| 67 | unsigned int ch; |
| 68 | struct tw686x_audio_buf *curr_bufs[2]; |
| 69 | struct tw686x_dma_desc dma_descs[2]; |
| 70 | dma_addr_t ptr; |
| 71 | |
| 72 | struct tw686x_audio_buf buf[TW686X_AUDIO_PAGE_MAX]; |
| 73 | struct list_head buf_list; |
| 74 | spinlock_t lock; |
| 75 | }; |
| 76 | |
| 77 | struct tw686x_video_channel { |
| 78 | struct tw686x_dev *dev; |
| 79 | |
| 80 | struct vb2_queue vidq; |
| 81 | struct list_head vidq_queued; |
| 82 | struct video_device *device; |
| 83 | struct tw686x_v4l2_buf *curr_bufs[2]; |
| 84 | struct tw686x_dma_desc dma_descs[2]; |
| 85 | |
| 86 | struct v4l2_ctrl_handler ctrl_handler; |
| 87 | const struct tw686x_format *format; |
| 88 | struct mutex vb_mutex; |
| 89 | spinlock_t qlock; |
| 90 | v4l2_std_id video_standard; |
| 91 | unsigned int width, height; |
| 92 | unsigned int h_halve, v_halve; |
| 93 | unsigned int ch; |
| 94 | unsigned int num; |
| 95 | unsigned int fps; |
| 96 | unsigned int input; |
| 97 | unsigned int sequence; |
| 98 | unsigned int pb; |
| 99 | bool no_signal; |
| 100 | }; |
| 101 | |
| 102 | /** |
| 103 | * struct tw686x_dev - global device status |
| 104 | * @lock: spinlock controlling access to the |
| 105 | * shared device registers (DMA enable/disable). |
| 106 | */ |
| 107 | struct tw686x_dev { |
| 108 | spinlock_t lock; |
| 109 | |
| 110 | struct v4l2_device v4l2_dev; |
| 111 | struct snd_card *snd_card; |
| 112 | |
| 113 | char name[32]; |
| 114 | unsigned int type; |
| 115 | struct pci_dev *pci_dev; |
| 116 | __u32 __iomem *mmio; |
| 117 | |
| 118 | void *alloc_ctx; |
| 119 | |
| 120 | struct tw686x_video_channel *video_channels; |
| 121 | struct tw686x_audio_channel *audio_channels; |
| 122 | |
| 123 | int audio_rate; /* per-device value */ |
| 124 | |
| 125 | struct timer_list dma_delay_timer; |
| 126 | u32 pending_dma_en; /* must be protected by lock */ |
| 127 | u32 pending_dma_cmd; /* must be protected by lock */ |
| 128 | }; |
| 129 | |
| 130 | static inline uint32_t reg_read(struct tw686x_dev *dev, unsigned int reg) |
| 131 | { |
| 132 | return readl(dev->mmio + reg); |
| 133 | } |
| 134 | |
| 135 | static inline void reg_write(struct tw686x_dev *dev, unsigned int reg, |
| 136 | uint32_t value) |
| 137 | { |
| 138 | writel(value, dev->mmio + reg); |
| 139 | } |
| 140 | |
| 141 | static inline unsigned int max_channels(struct tw686x_dev *dev) |
| 142 | { |
| 143 | return dev->type & TYPE_MAX_CHANNELS; /* 4 or 8 channels */ |
| 144 | } |
| 145 | |
| 146 | void tw686x_enable_channel(struct tw686x_dev *dev, unsigned int channel); |
| 147 | void tw686x_disable_channel(struct tw686x_dev *dev, unsigned int channel); |
| 148 | |
| 149 | int tw686x_video_init(struct tw686x_dev *dev); |
| 150 | void tw686x_video_free(struct tw686x_dev *dev); |
| 151 | void tw686x_video_irq(struct tw686x_dev *dev, unsigned long requests, |
| 152 | unsigned int pb_status, unsigned int fifo_status, |
| 153 | unsigned int *reset_ch); |
| 154 | |
| 155 | int tw686x_audio_init(struct tw686x_dev *dev); |
| 156 | void tw686x_audio_free(struct tw686x_dev *dev); |
| 157 | void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests, |
| 158 | unsigned int pb_status); |