1 #pragma once
2 /*
3  * This file is part of the libCEC(R) library.
4  *
5  * libCEC(R) is Copyright (C) 2011-2015 Pulse-Eight Limited.  All rights reserved.
6  * libCEC(R) is an original work, containing original code.
7  *
8  * libCEC(R) is a trademark of Pulse-Eight Limited.
9  *
10  * This program is dual-licensed; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23  * 02110-1301  USA
24  *
25  *
26  * Alternatively, you can license this library under a commercial license,
27  * please contact Pulse-Eight Licensing for more information.
28  *
29  * For more information contact:
30  * Pulse-Eight Licensing       <license@pulse-eight.com>
31  *     http://www.pulse-eight.com/
32  *     http://www.pulse-eight.net/
33  */
34 
35 #include "env.h"
36 #if defined(HAVE_RPI_API)
37 
38 #include "adapter/AdapterCommunication.h"
39 #include "p8-platform/threads/threads.h"
40 
41 #define RPI_ADAPTER_VID 0x2708
42 #define RPI_ADAPTER_PID 0x1001
43 
44 extern "C" {
45 #include <interface/vmcs_host/vc_cecservice.h>
46 #include <interface/vchiq_arm/vchiq_if.h>
47 }
48 
49 namespace CEC
50 {
51   class CRPiCECAdapterMessageQueue;
52 
53   class CRPiCECAdapterCommunication : public IAdapterCommunication
54   {
55   public:
56     /*!
57      * @brief Create a new USB-CEC communication handler.
58      * @param callback The callback to use for incoming CEC commands.
59      */
60     CRPiCECAdapterCommunication(IAdapterCommunicationCallback *callback);
61     virtual ~CRPiCECAdapterCommunication(void);
62 
63     /** @name IAdapterCommunication implementation */
64     ///{
65     bool Open(uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT, bool bSkipChecks = false, bool bStartListening = true);
66     void Close(void);
IsOpen(void)67     bool IsOpen(void) { return m_bInitialised; };
68     std::string GetError(void) const;
69     cec_adapter_message_state Write(const cec_command &data, bool &bRetry, uint8_t iLineTimeout, bool bIsReply);
70 
SetLineTimeout(uint8_t UNUSED (iTimeout))71     bool SetLineTimeout(uint8_t UNUSED(iTimeout)) { return true; };
StartBootloader(void)72     bool StartBootloader(void) { return false; };
73     bool SetLogicalAddresses(const cec_logical_addresses &addresses);
74     cec_logical_addresses GetLogicalAddresses(void) const;
PingAdapter(void)75     bool PingAdapter(void) { return m_bInitialised; };
76     uint16_t GetFirmwareVersion(void);
GetFirmwareBuildDate(void)77     uint32_t GetFirmwareBuildDate(void) { return 0; };
IsRunningLatestFirmware(void)78     bool IsRunningLatestFirmware(void) { return true; };
SaveConfiguration(const libcec_configuration & UNUSED (configuration))79     bool SaveConfiguration(const libcec_configuration & UNUSED(configuration)) { return false; };
GetConfiguration(libcec_configuration & UNUSED (configuration))80     bool GetConfiguration(libcec_configuration & UNUSED(configuration)) { return false; };
SetAutoMode(bool UNUSED (automode))81     bool SetAutoMode(bool UNUSED(automode)) { return false; }
GetPortName(void)82     std::string GetPortName(void) { std::string strReturn("RPI"); return strReturn; };
83     uint16_t GetPhysicalAddress(void);
SetControlledMode(bool UNUSED (controlled))84     bool SetControlledMode(bool UNUSED(controlled)) { return true; };
GetVendorId(void)85     cec_vendor_id GetVendorId(void) { return CEC_VENDOR_BROADCOM; }
SupportsSourceLogicalAddress(const cec_logical_address address)86     bool SupportsSourceLogicalAddress(const cec_logical_address address) { return address > CECDEVICE_TV && address < CECDEVICE_BROADCAST; }
GetAdapterType(void)87     cec_adapter_type GetAdapterType(void) { return ADAPTERTYPE_RPI; };
GetAdapterVendorId(void)88     uint16_t GetAdapterVendorId(void) const { return RPI_ADAPTER_VID; }
GetAdapterProductId(void)89     uint16_t GetAdapterProductId(void) const { return RPI_ADAPTER_PID; }
SetActiveSource(bool UNUSED (bSetTo),bool UNUSED (bClientUnregistered))90     void SetActiveSource(bool UNUSED(bSetTo), bool UNUSED(bClientUnregistered)) {}
91     #if CEC_LIB_VERSION_MAJOR >= 5
GetStats(struct cec_adapter_stats * UNUSED (stats))92     bool GetStats(struct cec_adapter_stats* UNUSED(stats)) { return false; }
93     #endif
94     ///}
95 
96     bool IsInitialised(void);
97     void OnDataReceived(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
98     void OnTVServiceCallback(uint32_t reason, uint32_t p0, uint32_t p1);
99 
100     static void InitHost(void);
101 
102   private:
103     cec_logical_address GetLogicalAddress(void) const;
104     bool UnregisterLogicalAddress(void);
105     bool RegisterLogicalAddress(const cec_logical_address address, uint32_t iTimeoutMs = CEC_DEFAULT_CONNECT_TIMEOUT);
106     void SetDisableCallback(const bool disable);
107 
108     bool m_bInitialised;   /**< true when the connection is initialised, false otherwise */
109     std::string m_strError; /**< current error message */
110     CRPiCECAdapterMessageQueue *m_queue;
111     cec_logical_address         m_logicalAddress;
112 
113     bool                          m_bLogicalAddressChanged;
114     P8PLATFORM::CCondition<bool>  m_logicalAddressCondition;
115     mutable P8PLATFORM::CMutex    m_mutex;
116     VCHI_INSTANCE_T               m_vchi_instance;
117     VCHI_CONNECTION_T *           m_vchi_connection;
118     cec_logical_address           m_previousLogicalAddress;
119     bool                          m_bLogicalAddressRegistered;
120 
121     bool                          m_bDisableCallbacks;
122   };
123 };
124 
125 #endif
126