libcec-imx6-support.patch 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. diff -Naur libcec-2.2.0/configure.ac libcec-2.2.0.patch/configure.ac
  2. --- libcec-2.2.0/configure.ac 2014-11-01 01:51:37.000000000 +0100
  3. +++ libcec-2.2.0.patch/configure.ac 2014-11-10 23:14:45.210162950 +0100
  4. @@ -100,6 +100,14 @@
  5. esac
  6. fi
  7. +## i.MX6 support
  8. +AC_ARG_ENABLE([imx6],
  9. + [AS_HELP_STRING([--enable-imx6],
  10. + [enable support for freescale i.MX6 (default is no)])],
  11. + [use_imx6=$enableval],
  12. + [use_imx6=no])
  13. +
  14. +
  15. ## add the top dir and include to the include path, so we can include config.h and cec.h
  16. CPPFLAGS="$CPPFLAGS -I\$(abs_top_srcdir)/src -I\$(abs_top_srcdir)/include"
  17. @@ -306,6 +314,17 @@
  18. fi
  19. +## mark i.MX6 support as available
  20. +if test "x$use_imx6" != "xno"; then
  21. + AC_DEFINE([HAVE_IMX_API],[1],[Define to 1 to include i.MX6 support])
  22. + AM_CONDITIONAL(USE_IMX_API, true)
  23. + features="$features\n i.MX6 support :\t\t\tyes"
  24. + LIB_INFO="$LIB_INFO 'i.MX6'"
  25. +else
  26. + AM_CONDITIONAL(USE_IMX_API, false)
  27. + features="$features\n i.MX6 support :\t\t\tno"
  28. +fi
  29. +
  30. ## check if our build system is complete
  31. AC_CHECK_HEADER(algorithm,,AC_MSG_ERROR($msg_required_header_missing))
  32. AC_CHECK_HEADER(ctype.h,,AC_MSG_ERROR($msg_required_header_missing))
  33. diff -Naur libcec-2.2.0/include/cectypes.h libcec-2.2.0.patch/include/cectypes.h
  34. --- libcec-2.2.0/include/cectypes.h 2014-10-28 16:20:50.000000000 +0100
  35. +++ libcec-2.2.0.patch/include/cectypes.h 2014-11-10 23:21:37.347945493 +0100
  36. @@ -307,6 +307,17 @@
  37. #define CEC_EXYNOS_VIRTUAL_COM "Exynos"
  38. /*!
  39. + * the path to use for the i.MX CEC wire
  40. + */
  41. +#define CEC_IMX_PATH "/dev/mxc_hdmi_cec"
  42. +
  43. +/*!
  44. + * the name of the virtual COM port to use for the i.MX CEC wire
  45. + */
  46. +#define CEC_IMX_VIRTUAL_COM "i.MX"
  47. +
  48. +
  49. +/*!
  50. * Mimimum client version
  51. */
  52. #define CEC_MIN_LIB_VERSION 2
  53. @@ -888,7 +899,8 @@
  54. ADAPTERTYPE_P8_DAUGHTERBOARD = 0x2,
  55. ADAPTERTYPE_RPI = 0x100,
  56. ADAPTERTYPE_TDA995x = 0x200,
  57. - ADAPTERTYPE_EXYNOS = 0x300
  58. + ADAPTERTYPE_EXYNOS = 0x300,
  59. + ADAPTERTYPE_IMX = 0x400
  60. } cec_adapter_type;
  61. typedef struct cec_menu_language
  62. diff -Naur libcec-2.2.0/src/lib/adapter/AdapterFactory.cpp libcec-2.2.0.patch/src/lib/adapter/AdapterFactory.cpp
  63. --- libcec-2.2.0/src/lib/adapter/AdapterFactory.cpp 2014-10-28 16:20:50.000000000 +0100
  64. +++ libcec-2.2.0.patch/src/lib/adapter/AdapterFactory.cpp 2014-11-10 23:18:08.761485552 +0100
  65. @@ -57,6 +57,11 @@
  66. #include "Exynos/ExynosCECAdapterCommunication.h"
  67. #endif
  68. +#if defined(HAVE_IMX_API)
  69. +#include "IMX/IMXCECAdapterDetection.h"
  70. +#include "IMX/IMXCECAdapterCommunication.h"
  71. +#endif
  72. +
  73. using namespace std;
  74. using namespace CEC;
  75. @@ -127,7 +132,22 @@
  76. #endif
  77. -#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API)
  78. +
  79. +#if defined(HAVE_IMX_API)
  80. + if (iAdaptersFound < iBufSize && CIMXCECAdapterDetection::FindAdapter() &&
  81. + (!strDevicePath || !strcmp(strDevicePath, CEC_IMX_VIRTUAL_COM)))
  82. + {
  83. + snprintf(deviceList[iAdaptersFound].strComPath, sizeof(deviceList[iAdaptersFound].strComPath), CEC_IMX_PATH);
  84. + snprintf(deviceList[iAdaptersFound].strComName, sizeof(deviceList[iAdaptersFound].strComName), CEC_IMX_VIRTUAL_COM);
  85. + deviceList[iAdaptersFound].iVendorId = IMX_ADAPTER_VID;
  86. + deviceList[iAdaptersFound].iProductId = IMX_ADAPTER_PID;
  87. + deviceList[iAdaptersFound].adapterType = ADAPTERTYPE_IMX;
  88. + iAdaptersFound++;
  89. + }
  90. +#endif
  91. +
  92. +
  93. +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_IMX_API)
  94. #error "libCEC doesn't have support for any type of adapter. please check your build system or configuration"
  95. #endif
  96. @@ -151,11 +171,16 @@
  97. return new CRPiCECAdapterCommunication(m_lib->m_cec);
  98. #endif
  99. +#if defined(HAVE_IMX_API)
  100. + if (!strcmp(strPort, CEC_IMX_VIRTUAL_COM))
  101. + return new CIMXCECAdapterCommunication(m_lib->m_cec);
  102. +#endif
  103. +
  104. #if defined(HAVE_P8_USB)
  105. return new CUSBCECAdapterCommunication(m_lib->m_cec, strPort, iBaudRate);
  106. #endif
  107. -#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API)
  108. +#if !defined(HAVE_RPI_API) && !defined(HAVE_P8_USB) && !defined(HAVE_TDA995X_API) && !defined(HAVE_EXYNOS_API) && !defined(HAVE_IMX_API)
  109. return NULL;
  110. #endif
  111. }
  112. diff -Naur libcec-2.2.0/src/lib/adapter/IMX/AdapterMessageQueue.h libcec-2.2.0.patch/src/lib/adapter/IMX/AdapterMessageQueue.h
  113. --- libcec-2.2.0/src/lib/adapter/IMX/AdapterMessageQueue.h 1970-01-01 01:00:00.000000000 +0100
  114. +++ libcec-2.2.0.patch/src/lib/adapter/IMX/AdapterMessageQueue.h 2014-11-10 23:14:45.214162390 +0100
  115. @@ -0,0 +1,134 @@
  116. +#pragma once
  117. +/*
  118. + * This file is part of the libCEC(R) library.
  119. + *
  120. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
  121. + * libCEC(R) is an original work, containing original code.
  122. + *
  123. + * libCEC(R) is a trademark of Pulse-Eight Limited.
  124. + *
  125. + * This program is dual-licensed; you can redistribute it and/or modify
  126. + * it under the terms of the GNU General Public License as published by
  127. + * the Free Software Foundation; either version 2 of the License, or
  128. + * (at your option) any later version.
  129. + *
  130. + * This program is distributed in the hope that it will be useful,
  131. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  132. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  133. + * GNU General Public License for more details.
  134. + *
  135. + * You should have received a copy of the GNU General Public License
  136. + * along with this program; if not, write to the Free Software
  137. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  138. + *
  139. + *
  140. + * Alternatively, you can license this library under a commercial license,
  141. + * please contact Pulse-Eight Licensing for more information.
  142. + *
  143. + * For more information contact:
  144. + * Pulse-Eight Licensing <license@pulse-eight.com>
  145. + * http://www.pulse-eight.com/
  146. + * http://www.pulse-eight.net/
  147. + */
  148. +
  149. +#include "lib/platform/threads/mutex.h"
  150. +
  151. +namespace CEC
  152. +{
  153. + using namespace PLATFORM;
  154. +
  155. + class CAdapterMessageQueueEntry
  156. + {
  157. + public:
  158. + CAdapterMessageQueueEntry(const cec_command &command)
  159. + : m_bWaiting(true), m_retval((uint32_t)-1), m_bSucceeded(false)
  160. + {
  161. + m_hash = hashValue(
  162. + uint32_t(command.opcode_set ? command.opcode : CEC_OPCODE_NONE),
  163. + command.initiator, command.destination);
  164. + }
  165. +
  166. + virtual ~CAdapterMessageQueueEntry(void) {}
  167. +
  168. + /*!
  169. + * @brief Query result from worker thread
  170. + */
  171. + uint32_t Result() const
  172. + {
  173. + return m_retval;
  174. + }
  175. +
  176. + /*!
  177. + * @brief Signal waiting threads
  178. + */
  179. + void Broadcast(void)
  180. + {
  181. + CLockObject lock(m_mutex);
  182. + m_condition.Broadcast();
  183. + }
  184. +
  185. + /*!
  186. + * @brief Signal waiting thread(s) when message matches this entry
  187. + */
  188. + bool CheckMatch(uint32_t opcode, cec_logical_address initiator,
  189. + cec_logical_address destination, uint32_t response)
  190. + {
  191. + uint32_t hash = hashValue(opcode, initiator, destination);
  192. +
  193. + if (hash == m_hash)
  194. + {
  195. + CLockObject lock(m_mutex);
  196. +
  197. + m_retval = response;
  198. + m_bSucceeded = true;
  199. + m_condition.Signal();
  200. + return true;
  201. + }
  202. +
  203. + return false;
  204. + }
  205. +
  206. + /*!
  207. + * @brief Wait for a response to this command.
  208. + * @param iTimeout The timeout to use while waiting.
  209. + * @return True when a response was received before the timeout passed, false otherwise.
  210. + */
  211. + bool Wait(uint32_t iTimeout)
  212. + {
  213. + CLockObject lock(m_mutex);
  214. +
  215. + bool bReturn = m_bSucceeded ? true : m_condition.Wait(m_mutex, m_bSucceeded, iTimeout);
  216. + m_bWaiting = false;
  217. + return bReturn;
  218. + }
  219. +
  220. + /*!
  221. + * @return True while a thread is waiting for a signal or isn't waiting yet, false otherwise.
  222. + */
  223. + bool IsWaiting(void)
  224. + {
  225. + CLockObject lock(m_mutex);
  226. + return m_bWaiting;
  227. + }
  228. +
  229. + /*!
  230. + * @return Hash value for given cec_command
  231. + */
  232. + static uint32_t hashValue(uint32_t opcode,
  233. + cec_logical_address initiator,
  234. + cec_logical_address destination)
  235. + {
  236. + return 1 | ((uint32_t)initiator << 8) |
  237. + ((uint32_t)destination << 16) | ((uint32_t)opcode << 16);
  238. + }
  239. +
  240. + private:
  241. + bool m_bWaiting; /**< true while a thread is waiting or when it hasn't started waiting yet */
  242. + PLATFORM::CCondition<bool> m_condition; /**< the condition to wait on */
  243. + PLATFORM::CMutex m_mutex; /**< mutex for changes to this class */
  244. + uint32_t m_hash;
  245. + uint32_t m_retval;
  246. + bool m_bSucceeded;
  247. + };
  248. +
  249. +};
  250. diff -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp
  251. --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp 1970-01-01 01:00:00.000000000 +0100
  252. +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.cpp 2014-11-10 23:14:45.217161982 +0100
  253. @@ -0,0 +1,328 @@
  254. +/*
  255. + * This file is part of the libCEC(R) library.
  256. + *
  257. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
  258. + * libCEC(R) is an original work, containing original code.
  259. + *
  260. + * libCEC(R) is a trademark of Pulse-Eight Limited.
  261. + *
  262. + * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
  263. + *
  264. + * You can redistribute this file and/or modify
  265. + * it under the terms of the GNU General Public License as published by
  266. + * the Free Software Foundation; either version 2 of the License, or
  267. + * (at your option) any later version.
  268. + *
  269. + * This program is distributed in the hope that it will be useful,
  270. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  271. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  272. + * GNU General Public License for more details.
  273. + *
  274. + * You should have received a copy of the GNU General Public License
  275. + * along with this program; if not, write to the Free Software
  276. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  277. + *
  278. + *
  279. + */
  280. +
  281. +#include "env.h"
  282. +
  283. +#if defined(HAVE_IMX_API)
  284. +#include "IMXCECAdapterCommunication.h"
  285. +
  286. +#include "lib/CECTypeUtils.h"
  287. +#include "lib/LibCEC.h"
  288. +#include "lib/platform/sockets/cdevsocket.h"
  289. +#include "lib/platform/util/StdString.h"
  290. +#include "lib/platform/util/buffer.h"
  291. +
  292. +/*
  293. + * Ioctl definitions from kernel header
  294. + */
  295. +#define HDMICEC_IOC_MAGIC 'H'
  296. +#define HDMICEC_IOC_SETLOGICALADDRESS _IOW(HDMICEC_IOC_MAGIC, 1, unsigned char)
  297. +#define HDMICEC_IOC_STARTDEVICE _IO(HDMICEC_IOC_MAGIC, 2)
  298. +#define HDMICEC_IOC_STOPDEVICE _IO(HDMICEC_IOC_MAGIC, 3)
  299. +#define HDMICEC_IOC_GETPHYADDRESS _IOR(HDMICEC_IOC_MAGIC, 4, unsigned char[4])
  300. +
  301. +#define MAX_CEC_MESSAGE_LEN 17
  302. +
  303. +#define MESSAGE_TYPE_RECEIVE_SUCCESS 1
  304. +#define MESSAGE_TYPE_NOACK 2
  305. +#define MESSAGE_TYPE_DISCONNECTED 3
  306. +#define MESSAGE_TYPE_CONNECTED 4
  307. +#define MESSAGE_TYPE_SEND_SUCCESS 5
  308. +
  309. +typedef struct hdmi_cec_event{
  310. + int event_type;
  311. + int msg_len;
  312. + unsigned char msg[MAX_CEC_MESSAGE_LEN];
  313. +}hdmi_cec_event;
  314. +
  315. +
  316. +using namespace std;
  317. +using namespace CEC;
  318. +using namespace PLATFORM;
  319. +
  320. +#include "AdapterMessageQueue.h"
  321. +
  322. +#define LIB_CEC m_callback->GetLib()
  323. +
  324. +// these are defined in nxp private header file
  325. +#define CEC_MSG_SUCCESS 0x00 /*Message transmisson Succeed*/
  326. +#define CEC_CSP_OFF_STATE 0x80 /*CSP in Off State*/
  327. +#define CEC_BAD_REQ_SERVICE 0x81 /*Bad .req service*/
  328. +#define CEC_MSG_FAIL_UNABLE_TO_ACCESS 0x82 /*Message transmisson failed: Unable to access CEC line*/
  329. +#define CEC_MSG_FAIL_ARBITRATION_ERROR 0x83 /*Message transmisson failed: Arbitration error*/
  330. +#define CEC_MSG_FAIL_BIT_TIMMING_ERROR 0x84 /*Message transmisson failed: Bit timming error*/
  331. +#define CEC_MSG_FAIL_DEST_NOT_ACK 0x85 /*Message transmisson failed: Destination Address not aknowledged*/
  332. +#define CEC_MSG_FAIL_DATA_NOT_ACK 0x86 /*Message transmisson failed: Databyte not acknowledged*/
  333. +
  334. +
  335. +CIMXCECAdapterCommunication::CIMXCECAdapterCommunication(IAdapterCommunicationCallback *callback) :
  336. + IAdapterCommunication(callback)/*,
  337. + m_bLogicalAddressChanged(false)*/
  338. +{
  339. + CLockObject lock(m_mutex);
  340. +
  341. + m_iNextMessage = 0;
  342. + //m_logicalAddresses.Clear();
  343. + m_logicalAddress = CECDEVICE_UNKNOWN;
  344. + m_bLogicalAddressRegistered = false;
  345. + m_bInitialised = false;
  346. + m_dev = new CCDevSocket(CEC_IMX_PATH);
  347. +}
  348. +
  349. +CIMXCECAdapterCommunication::~CIMXCECAdapterCommunication(void)
  350. +{
  351. + Close();
  352. +
  353. + CLockObject lock(m_mutex);
  354. + delete m_dev;
  355. + m_dev = 0;
  356. +}
  357. +
  358. +bool CIMXCECAdapterCommunication::IsOpen(void)
  359. +{
  360. + return IsInitialised() && m_dev->IsOpen();
  361. +}
  362. +
  363. +bool CIMXCECAdapterCommunication::Open(uint32_t iTimeoutMs, bool UNUSED(bSkipChecks), bool bStartListening)
  364. +{
  365. + if (m_dev->Open(iTimeoutMs))
  366. + {
  367. + if (!bStartListening || CreateThread()) {
  368. + if (m_dev->Ioctl(HDMICEC_IOC_STARTDEVICE, NULL) == 0) {
  369. + m_bInitialised = true;
  370. + return true;
  371. + }
  372. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to start device\n", __func__);
  373. + }
  374. + m_dev->Close();
  375. + }
  376. +
  377. + return false;
  378. +}
  379. +
  380. +
  381. +void CIMXCECAdapterCommunication::Close(void)
  382. +{
  383. + StopThread(0);
  384. +
  385. + CLockObject lock(m_mutex);
  386. + if (!m_bInitialised) {
  387. + return;
  388. + }
  389. + if (m_dev->Ioctl(HDMICEC_IOC_STOPDEVICE, NULL) != 0) {
  390. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: Unable to stop device\n", __func__);
  391. + }
  392. + m_dev->Close();
  393. + m_bInitialised = false;
  394. +}
  395. +
  396. +
  397. +std::string CIMXCECAdapterCommunication::GetError(void) const
  398. +{
  399. + std::string strError(m_strError);
  400. + return strError;
  401. +}
  402. +
  403. +
  404. +cec_adapter_message_state CIMXCECAdapterCommunication::Write(
  405. + const cec_command &data, bool &UNUSED(bRetry), uint8_t UNUSED(iLineTimeout), bool UNUSED(bIsReply))
  406. +{
  407. + //cec_frame frame;
  408. + unsigned char message[MAX_CEC_MESSAGE_LEN];
  409. + int msg_len = 1;
  410. + cec_adapter_message_state rc = ADAPTER_MESSAGE_STATE_ERROR;
  411. +
  412. + if ((size_t)data.parameters.size + data.opcode_set + 1 > sizeof(message))
  413. + {
  414. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: data size too large !", __func__);
  415. + return ADAPTER_MESSAGE_STATE_ERROR;
  416. + }
  417. +
  418. + message[0] = (data.initiator << 4) | (data.destination & 0x0f);
  419. + if (data.opcode_set)
  420. + {
  421. + message[1] = data.opcode;
  422. + msg_len++;
  423. + memcpy(&message[2], data.parameters.data, data.parameters.size);
  424. + msg_len+=data.parameters.size;
  425. + }
  426. +
  427. + if (m_dev->Write(message, msg_len) == msg_len)
  428. + {
  429. + rc = ADAPTER_MESSAGE_STATE_SENT_ACKED;
  430. + }
  431. + else
  432. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: sent command error !", __func__);
  433. +
  434. + return rc;
  435. +}
  436. +
  437. +
  438. +uint16_t CIMXCECAdapterCommunication::GetFirmwareVersion(void)
  439. +{
  440. + /* FIXME add ioctl ? */
  441. + return 0;
  442. +}
  443. +
  444. +
  445. +cec_vendor_id CIMXCECAdapterCommunication::GetVendorId(void)
  446. +{
  447. + return CEC_VENDOR_UNKNOWN;
  448. +}
  449. +
  450. +
  451. +uint16_t CIMXCECAdapterCommunication::GetPhysicalAddress(void)
  452. +{
  453. + uint32_t info;
  454. + uint16_t phy_addr;
  455. +
  456. + if (m_dev->Ioctl(HDMICEC_IOC_GETPHYADDRESS, &info) != 0)
  457. + {
  458. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_GETPHYADDRESS failed !", __func__);
  459. + return CEC_INVALID_PHYSICAL_ADDRESS;
  460. + }
  461. + /* Rebuild 16 bit raw value from fsl 32 bits value */
  462. + phy_addr = ((info & 0x0f) << 12) | (info & 0x0f00) |
  463. + ((info & 0x0f0000) >> 12) | ((info & 0x0f000000) >> 24);
  464. +
  465. + return phy_addr;
  466. +}
  467. +
  468. +
  469. +cec_logical_addresses CIMXCECAdapterCommunication::GetLogicalAddresses(void)
  470. +{
  471. + cec_logical_addresses addresses;
  472. + addresses.Clear();
  473. +
  474. + CLockObject lock(m_mutex);
  475. + if ((m_logicalAddress & (CECDEVICE_UNKNOWN | CECDEVICE_UNREGISTERED)) == 0)
  476. + addresses.Set(m_logicalAddress);
  477. +
  478. + return addresses;
  479. +}
  480. +
  481. +void CIMXCECAdapterCommunication::HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress))
  482. +{
  483. + UnregisterLogicalAddress();
  484. +}
  485. +
  486. +bool CIMXCECAdapterCommunication::UnregisterLogicalAddress(void)
  487. +{
  488. + CLockObject lock(m_mutex);
  489. + if (!m_bLogicalAddressRegistered)
  490. + return true;
  491. +
  492. + if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)CECDEVICE_BROADCAST) != 0)
  493. + {
  494. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
  495. + return false;
  496. + }
  497. +
  498. + m_logicalAddress = CECDEVICE_UNKNOWN;
  499. + m_bLogicalAddressRegistered = false;
  500. + return true;
  501. +}
  502. +
  503. +bool CIMXCECAdapterCommunication::RegisterLogicalAddress(const cec_logical_address address)
  504. +{
  505. + CLockObject lock(m_mutex);
  506. +
  507. + if (m_logicalAddress == address && m_bLogicalAddressRegistered)
  508. + {
  509. + return true;
  510. + }
  511. +
  512. + if (m_dev->Ioctl(HDMICEC_IOC_SETLOGICALADDRESS, (void *)address) != 0)
  513. + {
  514. + LIB_CEC->AddLog(CEC_LOG_ERROR, "%s: HDMICEC_IOC_SETLOGICALADDRESS failed !", __func__);
  515. + return false;
  516. + }
  517. +
  518. + m_logicalAddress = address;
  519. + m_bLogicalAddressRegistered = true;
  520. + return true;
  521. +}
  522. +
  523. +bool CIMXCECAdapterCommunication::SetLogicalAddresses(const cec_logical_addresses &addresses)
  524. +{
  525. + int log_addr = addresses.primary;
  526. +
  527. + return RegisterLogicalAddress((cec_logical_address)log_addr);
  528. +}
  529. +
  530. +void *CIMXCECAdapterCommunication::Process(void)
  531. +{
  532. + bool bHandled;
  533. + hdmi_cec_event event;
  534. + int ret;
  535. +
  536. + uint32_t opcode, status;
  537. + cec_logical_address initiator, destination;
  538. +
  539. + while (!IsStopped())
  540. + {
  541. + ret = m_dev->Read((char *)&event, sizeof(event), 5000);
  542. + if (ret > 0)
  543. + {
  544. +
  545. + initiator = cec_logical_address(event.msg[0] >> 4);
  546. + destination = cec_logical_address(event.msg[0] & 0x0f);
  547. +
  548. + //LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read data : type : %d initiator %d dest %d", __func__, event.event_type, initiator, destination);
  549. + if (event.event_type == MESSAGE_TYPE_RECEIVE_SUCCESS)
  550. + /* Message received */
  551. + {
  552. + cec_command cmd;
  553. +
  554. + cec_command::Format(
  555. + cmd, initiator, destination,
  556. + ( event.msg_len > 1 ) ? cec_opcode(event.msg[1]) : CEC_OPCODE_NONE);
  557. +
  558. + for( uint8_t i = 2; i < event.msg_len; i++ )
  559. + cmd.parameters.PushBack(event.msg[i]);
  560. +
  561. + if (!IsStopped())
  562. + m_callback->OnCommandReceived(cmd);
  563. + }
  564. +
  565. + if (event.event_type == MESSAGE_TYPE_CONNECTED)
  566. + /* HDMI has just been reconnected - Notify phy address*/
  567. + {
  568. + uint16_t iNewAddress = GetPhysicalAddress();
  569. + m_callback->HandlePhysicalAddressChanged(iNewAddress);
  570. + }
  571. + /* We are not interested in other events */
  572. + } /*else {
  573. + LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: Read returned %d", __func__, ret);
  574. + }*/
  575. +
  576. + }
  577. +
  578. + return 0;
  579. +}
  580. +
  581. +#endif // HAVE_IMX_API
  582. diff -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.h libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.h
  583. --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterCommunication.h 1970-01-01 01:00:00.000000000 +0100
  584. +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterCommunication.h 2014-11-10 23:14:45.217161982 +0100
  585. @@ -0,0 +1,119 @@
  586. +#pragma once
  587. +/*
  588. + * This file is part of the libCEC(R) library.
  589. + *
  590. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
  591. + * libCEC(R) is an original work, containing original code.
  592. + *
  593. + * libCEC(R) is a trademark of Pulse-Eight Limited.
  594. + *
  595. + * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
  596. + *
  597. + * You can redistribute this file and/or modify
  598. + * it under the terms of the GNU General Public License as published by
  599. + * the Free Software Foundation; either version 2 of the License, or
  600. + * (at your option) any later version.
  601. + *
  602. + * This program is distributed in the hope that it will be useful,
  603. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  604. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  605. + * GNU General Public License for more details.
  606. + *
  607. + * You should have received a copy of the GNU General Public License
  608. + * along with this program; if not, write to the Free Software
  609. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  610. + *
  611. + *
  612. + */
  613. +
  614. +#if defined(HAVE_IMX_API)
  615. +
  616. +#include "lib/platform/threads/mutex.h"
  617. +#include "lib/platform/threads/threads.h"
  618. +#include "lib/platform/sockets/socket.h"
  619. +#include "lib/adapter/AdapterCommunication.h"
  620. +#include <map>
  621. +
  622. +#define IMX_ADAPTER_VID 0x0471 /*FIXME TBD*/
  623. +#define IMX_ADAPTER_PID 0x1001
  624. +
  625. +
  626. +
  627. +namespace PLATFORM
  628. +{
  629. + class CCDevSocket;
  630. +};
  631. +
  632. +
  633. +namespace CEC
  634. +{
  635. + class CAdapterMessageQueueEntry;
  636. +
  637. + class CIMXCECAdapterCommunication : public IAdapterCommunication, public PLATFORM::CThread
  638. + {
  639. + public:
  640. + /*!
  641. + * @brief Create a new USB-CEC communication handler.
  642. + * @param callback The callback to use for incoming CEC commands.
  643. + */
  644. + CIMXCECAdapterCommunication(IAdapterCommunicationCallback *callback);
  645. + virtual ~CIMXCECAdapterCommunication(void);
  646. +
  647. + /** @name IAdapterCommunication implementation */
  648. + ///{
  649. + bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true);
  650. + void Close(void);
  651. + bool IsOpen(void);
  652. + std::string GetError(void) const;
  653. + cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply);
  654. +
  655. + bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; }
  656. + bool StartBootloader(void) { return false; }
  657. + bool SetLogicalAddresses(const cec_logical_addresses &addresses);
  658. + cec_logical_addresses GetLogicalAddresses(void);
  659. + bool PingAdapter(void) { return IsInitialised(); }
  660. + uint16_t GetFirmwareVersion(void);
  661. + uint32_t GetFirmwareBuildDate(void) { return 0; }
  662. + bool IsRunningLatestFirmware(void) { return true; }
  663. + bool PersistConfiguration(const libcec_configuration & UNUSED(configuration)) { return false; }
  664. + bool GetConfiguration(libcec_configuration & UNUSED(configuration)) { return false; }
  665. + std::string GetPortName(void) { return std::string("IMX"); }
  666. + uint16_t GetPhysicalAddress(void);
  667. + bool SetControlledMode(bool UNUSED(controlled)) { return true; }
  668. + cec_vendor_id GetVendorId(void);
  669. + bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address <= CECDEVICE_BROADCAST; }
  670. + cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_IMX; }
  671. + uint16_t GetAdapterVendorId(void) const { return IMX_ADAPTER_VID; }
  672. + uint16_t GetAdapterProductId(void) const { return IMX_ADAPTER_PID; }
  673. + void HandleLogicalAddressLost(cec_logical_address UNUSED(oldAddress));
  674. + void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
  675. + bool RegisterLogicalAddress(const cec_logical_address address);
  676. + ///}
  677. +
  678. + /** @name PLATFORM::CThread implementation */
  679. + ///{
  680. + void *Process(void);
  681. + ///}
  682. +
  683. + private:
  684. + bool IsInitialised(void) const { return m_bInitialised; };
  685. + bool UnregisterLogicalAddress(void);
  686. +
  687. + std::string m_strError; /**< current error message */
  688. +
  689. + //cec_logical_addresses m_logicalAddresses;
  690. + cec_logical_address m_logicalAddress;
  691. +
  692. + PLATFORM::CMutex m_mutex;
  693. + PLATFORM::CCDevSocket *m_dev; /**< the device connection */
  694. + bool m_bLogicalAddressRegistered;
  695. + bool m_bInitialised;
  696. +
  697. + PLATFORM::CMutex m_messageMutex;
  698. + uint32_t m_iNextMessage;
  699. + std::map<uint32_t, CAdapterMessageQueueEntry *> m_messages;
  700. + };
  701. +
  702. +};
  703. +
  704. +#endif
  705. diff -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp
  706. --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp 1970-01-01 01:00:00.000000000 +0100
  707. +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.cpp 2014-11-10 23:14:45.215162253 +0100
  708. @@ -0,0 +1,42 @@
  709. +/*
  710. + * This file is part of the libCEC(R) library.
  711. + *
  712. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
  713. + * libCEC(R) is an original work, containing original code.
  714. + *
  715. + * libCEC(R) is a trademark of Pulse-Eight Limited.
  716. + *
  717. + * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
  718. + *
  719. + * You can redistribute this file and/or modify
  720. + * it under the terms of the GNU General Public License as published by
  721. + * the Free Software Foundation; either version 2 of the License, or
  722. + * (at your option) any later version.
  723. + *
  724. + * This program is distributed in the hope that it will be useful,
  725. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  726. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  727. + * GNU General Public License for more details.
  728. + *
  729. + * You should have received a copy of the GNU General Public License
  730. + * along with this program; if not, write to the Free Software
  731. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  732. + *
  733. + *
  734. + */
  735. +
  736. +#include "env.h"
  737. +#include <stdio.h>
  738. +
  739. +#if defined(HAVE_IMX_API)
  740. +#include "IMXCECAdapterDetection.h"
  741. +
  742. +
  743. +using namespace CEC;
  744. +
  745. +bool CIMXCECAdapterDetection::FindAdapter(void)
  746. +{
  747. + return access(CEC_IMX_PATH, 0) == 0;
  748. +}
  749. +
  750. +#endif
  751. diff -Naur libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.h libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.h
  752. --- libcec-2.2.0/src/lib/adapter/IMX/IMXCECAdapterDetection.h 1970-01-01 01:00:00.000000000 +0100
  753. +++ libcec-2.2.0.patch/src/lib/adapter/IMX/IMXCECAdapterDetection.h 2014-11-10 23:14:45.215162253 +0100
  754. @@ -0,0 +1,36 @@
  755. +#pragma once
  756. +/*
  757. + * This file is part of the libCEC(R) library.
  758. + *
  759. + * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
  760. + * libCEC(R) is an original work, containing original code.
  761. + *
  762. + * libCEC(R) is a trademark of Pulse-Eight Limited.
  763. + *
  764. + * IMX adpater port is Copyright (C) 2013 by Stephan Rafin
  765. + *
  766. + * You can redistribute this file and/or modify
  767. + * it under the terms of the GNU General Public License as published by
  768. + * the Free Software Foundation; either version 2 of the License, or
  769. + * (at your option) any later version.
  770. + *
  771. + * This program is distributed in the hope that it will be useful,
  772. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  773. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  774. + * GNU General Public License for more details.
  775. + *
  776. + * You should have received a copy of the GNU General Public License
  777. + * along with this program; if not, write to the Free Software
  778. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  779. + *
  780. + *
  781. + */
  782. +
  783. +namespace CEC
  784. +{
  785. + class CIMXCECAdapterDetection
  786. + {
  787. + public:
  788. + static bool FindAdapter(void);
  789. + };
  790. +}
  791. diff -Naur libcec-2.2.0/src/lib/CECTypeUtils.h libcec-2.2.0.patch/src/lib/CECTypeUtils.h
  792. --- libcec-2.2.0/src/lib/CECTypeUtils.h 2014-10-28 16:20:50.000000000 +0100
  793. +++ libcec-2.2.0.patch/src/lib/CECTypeUtils.h 2014-11-10 23:14:45.212162668 +0100
  794. @@ -877,6 +877,8 @@
  795. return "Raspberry Pi";
  796. case ADAPTERTYPE_TDA995x:
  797. return "TDA995x";
  798. + case ADAPTERTYPE_IMX:
  799. + return "i.MX";
  800. default:
  801. return "unknown";
  802. }
  803. diff -Naur libcec-2.2.0/src/lib/Makefile.am libcec-2.2.0.patch/src/lib/Makefile.am
  804. --- libcec-2.2.0/src/lib/Makefile.am 2014-10-28 16:20:50.000000000 +0100
  805. +++ libcec-2.2.0.patch/src/lib/Makefile.am 2014-11-10 23:20:02.597700521 +0100
  806. @@ -63,6 +63,12 @@
  807. adapter/TDA995x/TDA995xCECAdapterCommunication.cpp
  808. endif
  809. +## i.MX6 support
  810. +if USE_IMX_API
  811. +libcec_la_SOURCES += adapter/IMX/IMXCECAdapterDetection.cpp \
  812. + adapter/IMX/IMXCECAdapterCommunication.cpp
  813. +endif
  814. +
  815. ## Exynos support
  816. if USE_EXYNOS_API
  817. libcec_la_SOURCES += adapter/Exynos/ExynosCECAdapterDetection.cpp \