1/*
2 * Copyright (c) 2003 by Siarzuk Zharski <imker@gmx.li>
3 *
4 * This file may be used under the terms of the BSD License
5 *
6 * Skeletal part of this code was inherired from original BeOS sample code,
7 * that is distributed under the terms of the Be Sample Code License.
8 *
9 */
10
11#include <support/Autolock.h>
12#include <media/MediaFormats.h>
13#include <Drivers.h>
14
15#include <stdio.h>
16#include <string.h>
17#include <unistd.h>
18
19#include "AddOn.h"
20#include "Producer.h"
21
22#include "nt100x.h"
23
24MediaAddOn::MediaAddOn(image_id imid)
25	: BMediaAddOn(imid)
26{
27	/* Customize these parameters to match those of your node */
28	fFlavorInfo.name = "USB Vision";
29	fFlavorInfo.info = "USB Vision";
30	fFlavorInfo.kinds = B_BUFFER_PRODUCER | B_CONTROLLABLE | B_PHYSICAL_INPUT;
31	fFlavorInfo.flavor_flags = 0;
32	fFlavorInfo.internal_id = 0;
33	fFlavorInfo.possible_count = 1;
34	fFlavorInfo.in_format_count = 0;
35	fFlavorInfo.in_format_flags = 0;
36	fFlavorInfo.in_formats = NULL;
37	fFlavorInfo.out_format_count = 1;
38	fFlavorInfo.out_format_flags = 0;
39	fMediaFormat.type = B_MEDIA_RAW_VIDEO;
40	fMediaFormat.u.raw_video = media_raw_video_format::wildcard;
41	fMediaFormat.u.raw_video.interlace = 1;
42	fMediaFormat.u.raw_video.display.format = B_RGB32;
43	fFlavorInfo.out_formats = &fMediaFormat;
44
45	fInitStatus = B_NO_INIT;
46    fDriverFD = -1;
47    if(USBVisionInit()){
48	  fInitStatus = B_OK;
49	}
50}
51
52MediaAddOn::~MediaAddOn()
53{
54  if(fInitStatus == B_OK){
55    USBVisionUninit();
56  }
57}
58
59
60status_t
61MediaAddOn::InitCheck(const char **out_failure_text)
62{
63	if (fInitStatus < B_OK) {
64		*out_failure_text = "Unknown error";
65		return fInitStatus;
66	}
67
68	return B_OK;
69}
70
71int32
72MediaAddOn::CountFlavors()
73{
74	if (fInitStatus < B_OK)
75		return fInitStatus;
76
77	/* This addon only supports a single flavor, as defined in the
78	 * constructor */
79	return 1;
80}
81
82/*
83 * The pointer to the flavor received only needs to be valid between
84 * successive calls to BMediaAddOn::GetFlavorAt().
85 */
86status_t
87MediaAddOn::GetFlavorAt(int32 n, const flavor_info **out_info)
88{
89	if (fInitStatus < B_OK)
90		return fInitStatus;
91
92	if (n != 0)
93		return B_BAD_INDEX;
94
95	/* Return the flavor defined in the constructor */
96	*out_info = &fFlavorInfo;
97	return B_OK;
98}
99
100BMediaNode *
101MediaAddOn::InstantiateNodeFor(
102		const flavor_info *info, BMessage *config, status_t *out_error)
103{
104	VideoProducer *node;
105
106	if (fInitStatus < B_OK)
107		return NULL;
108
109	if (info->internal_id != fFlavorInfo.internal_id)
110		return NULL;
111
112	/* At most one instance of the node should be instantiated at any given
113	 * time. The locking for this restriction may be found in the VideoProducer
114	 * class. */
115	node = new VideoProducer(this, fFlavorInfo.name, fFlavorInfo.internal_id);
116	if (node && (node->InitCheck() < B_OK)) {
117		delete node;
118		node = NULL;
119	}
120
121	return node;
122}
123
124BMediaAddOn *
125make_media_addon(image_id imid)
126{
127  return new MediaAddOn(imid);
128}
129
130bool MediaAddOn::USBVisionInit()
131{
132  //TODO - support for multiple devices !!!
133  fDriverFD = open("/dev/video/usb_vision/0", O_RDWR);
134  if(fDriverFD < 0)
135    fInitStatus = ENODEV;
136  return (fDriverFD >= 0);
137}
138
139void MediaAddOn::USBVisionUninit()
140{  //TODO - correct work on detach device from usb port ...
141  close(fDriverFD);
142}
143
144status_t MediaAddOn::USBVisionWriteRegister(uint8 reg, uint8 *data, uint8 len /*= sizeof(uint8)*/)
145{
146  status_t status = ENODEV;
147  if(fDriverFD >= 0){
148    xet_nt100x_reg ri = {reg, len};
149    memcpy(ri.data, data, len);
150    status = ioctl(fDriverFD, NT_IOCTL_WRITE_REGISTER, &ri, sizeof(ri));
151  }
152  return status;
153}
154
155status_t MediaAddOn::USBVisionReadRegister(uint8 reg, uint8 *data, uint8 len /* = sizeof(uint8)*/)
156{
157  status_t status = ENODEV;
158  if(fDriverFD >= 0){
159    xet_nt100x_reg ri = {reg, len};
160    if((status = ioctl(fDriverFD, NT_IOCTL_READ_REGISTER, &ri, sizeof(ri))) == B_OK){
161      memcpy(data, ri.data, ri.data_length);
162    }
163  }
164  return status;
165}
166